Додавання з плаваючою комою, без поплавків!


9

Ваше завдання - написати програму будь-якою мовою, яка додає два числа з плаваючою комою БЕЗ використання будь-якої математики дробової чи плаваючої точки. Математика з цілим числом дозволена.

Формат

Формат для чисел - це рядки, що містять 1 і 0, які представляють двійкове значення 32-бітного плаваючого кода IEEE 754 . Наприклад, число 2,54 буде представлено рядком "01000000001000101000111101011100".

Мета

Програма повинна ввести два числа у вищезгаданому форматі, додати їх разом і вивести результат у тому ж форматі. Найкоротша відповідь будь-якою мовою виграє!

Правила

Абсолютно ніякі функції з плаваючою комою, десятковими чи будь-якими не математичними функціями не допускаються.

Ви можете припустити, що вхід чистий (тобто містить лише 1 і 0).

Можна припустити, що вхідні дані - це числа, а не Inf, -Inf або NaN або субнормальні. Однак якщо результат більший за максимальне значення або менший за мінімальне значення, слід повернути Inf і -Inf відповідно. Субнормальний (денормальний) результат може бути зведений до 0.

Вам не доведеться правильно обробляти округлення. Не хвилюйтеся, якщо ваші результати вийдуть за кілька біт.

Тести

Щоб перевірити свої програми, ви можете перетворити між десятковими і двійковими числами з плаваючою комою за допомогою цього інструменту .

1000 + 0,5 = 1000,5

01000100011110100000000000000000 + 00111111000000000000000000000000 = 01000100011110100010000000000000

float.MaxValue + float.MaxValue = Нескінченність

01111111011111111111111111111111 + 01111111011111111111111111111111 = 01111111100000000000000000000000

321.123 + -123.321 = 197.802

01000011101000001000111110111110 + 11000010111101101010010001011010= 01000011010001011100110101010000

Удачі!

Відповіді:


3

Пітон, 224 символів

Цей код перетворює вхід fз плаваючою комою на ціле число f*2^150, робить додавання, використовуючи великі цілі числа python, а потім перетворює назад.

V=lambda x:((-1)**int(x[0])<<int(x[1:9],2))*int('1'+x[9:],2)
B=lambda x,n:B(x/2,n-1)+'01'[x&1]if n else''
def A(x,y):
 v=V(x)+V(y)
 s=e=0
 if v<0:s=1;v=-v
 while v>=1<<24:v/=2;e+=1
 if e>254:v=0
 return'%d'%s+B(e,8)+B(v,23)

3

J (172 символи)

Оскільки IEEE 754 дозволяє використовувати п'ять правил округлення, я вибрав правило "до 0". Ось мій код:

b=:(_1&^)@".@{.*[:#.1x,("."0)@(9&}.),#.@:("."0)@}.@(9&{.)$0:
a=:b@[([:,(<&0)":"0@:,,@((8$2)&#:)@(-&24)@$@#:,}.@(24&{.)@#:@|)@(]`(**2x^278"_)@.((>&((2x^278)-2x^254))@|))@+b@]

Самі ж приклади, які ви даєте (але не зовсім однакові результати через різні правила округлення):

   '01000100011110100000000000000000' a '00111111000000000000000000000000'
01000100011110100010000000000000
   '01111111011111111111111111111111' a '01111111011111111111111111111111'
01111111100000000000000000000000
   '01000011101000001000111110111110' a '11000010111101101010010001011010'
01000011010001011100110101001111
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.