Дополнение с плавающей точкой, без поплавков!


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.