Adición de punto flotante, sin flotadores!

9

Su tarea es escribir un programa, en cualquier idioma, que suma dos números de coma flotante juntos sin el uso de ningún matemáticas de punto flotante o fraccionarios. Se permiten las matemáticas enteras.

Formato

El formato de los números son cadenas que contienen 1 y 0 que representan el valor binario de un flotante IEEE 754 de 32 bits . Por ejemplo, el número 2.54 estaría representado por la cadena "01000000001000101000111101011100".

Objetivo

El programa debe ingresar dos números en el formato mencionado anteriormente, sumarlos y generar el resultado en el mismo formato. ¡La respuesta más corta en cualquier idioma gana!

Reglas

Absolutamente no se permiten las funciones matemáticas de coma flotante, decimales ni ningún tipo de entero.

Puede suponer que la entrada está limpia (es decir, contiene solo 1 y 0).

Puede suponer que las entradas son números y no Inf, -Inf o NaN o subnormal. Sin embargo, si el resultado es mayor que el valor máximo o menor que el valor mínimo, debe devolver Inf e -Inf respectivamente. Un resultado subnormal (denormal) se puede volcar a 0.

No tiene que manejar el redondeo correctamente. No te preocupes si tus resultados son pocos.

Pruebas

Para probar sus programas, puede convertir entre números binarios decimales y de coma flotante utilizando esta herramienta .

1000 + 0.5 = 1000.5

01000100011110100000000000000000 + 00111111000000000000000000000000 = 01000100011110100010000000000000

float.MaxValue + float.MaxValue = Infinity

01111111011111111111111111111111 + 01111111011111111111111111111111 = 01111111100000000000000000000000

321.123 + -123.321 = 197.802

01000011101000001000111110111110 + 11000010111101101010010001011010= 01000011010001011100110101010000

¡Buena suerte!

Hannesh
fuente

Respuestas:

3

Python, 224 caracteres

Este código convierte una entrada de punto flotante fal número entero f*2^150, realiza la suma usando enteros grandes nativos de Python y luego los vuelve a convertir.

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)
Keith Randall
fuente
3

J (172 caracteres)

Como IEEE 754 permite cinco reglas de redondeo, elegí la regla "hacia 0". Aquí está mi código:

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

Los mismos ejemplos que da (pero no exactamente los mismos resultados debido a la regla de redondeo diferente):

   '01000100011110100000000000000000' a '00111111000000000000000000000000'
01000100011110100010000000000000
   '01111111011111111111111111111111' a '01111111011111111111111111111111'
01111111100000000000000000000000
   '01000011101000001000111110111110' a '11000010111101101010010001011010'
01000011010001011100110101001111
Thomas Baruchel
fuente