Adição de ponto flutuante, sem flutuadores!

9

Sua tarefa é escrever um programa, em qualquer idioma, que adiciona dois números de ponto flutuante em conjunto, sem usar nenhum matemática ponto fracionários ou flutuantes. Matemática inteira é permitida.

Formato

O formato para os números são cadeias contendo 1 e 0 que representam o valor binário de um flutuador IEEE 754 de 32 bits . Por exemplo, o número 2.54 seria representado pela sequência "01000000001000101000111101011100".

Objetivo

Você programa deve inserir dois números no formato mencionado acima, adicioná-los e gerar o resultado no mesmo formato. A resposta mais curta em qualquer idioma vence!

Regras

Absolutamente nenhuma função de ponto flutuante, decimal ou qualquer tipo de função matemática não inteira é permitida.

Você pode assumir que a entrada está limpa (ou seja, contém apenas 1 e 0).

Você pode assumir que as entradas são números, e não Inf, -Inf ou NaN ou subnormal. No entanto, se o resultado for maior que o valor máximo ou menor que o valor mínimo, você deve retornar Inf e -Inf, respectivamente. Um resultado subnormal (desnormal) pode ser liberado para 0.

Você não precisa lidar com o arredondamento corretamente. Não se preocupe se seus resultados estiverem alguns minutos fora.

Testes

Para testar seus programas, você pode converter entre números binários decimais e de ponto flutuante usando esta ferramenta .

1000 + 0,5 = 1000,5

01000100011110100000000000000000 + 00111111000000000000000000000000 = 01000100011110100010000000000000

float.MaxValue + float.MaxValue = Infinito

01111111011111111111111111111111 + 01111111011111111111111111111111 = 01111111100000000000000000000000

321,123 + -123,321 = 197,802

01000011101000001000111110111110 + 11000010111101101010010001011010= 01000011010001011100110101010000

Boa sorte!

Hannesh
fonte

Respostas:

3

Python, 224 caracteres

Esse código converte uma entrada de ponto flutuante fem número inteiro f*2^150, faz a adição usando números inteiros grandes nativos em python e depois converte novamente.

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
fonte
3

J (172 caracteres)

Como o IEEE 754 permite cinco regras de arredondamento, eu escolhi a regra "em direção a 0". Aqui está o meu 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@]

Os mesmos exemplos que você fornece (mas não exatamente os mesmos resultados devido às diferentes regras de arredondamento):

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