Ajout de virgule flottante, sans flotteurs!

9

Votre tâche consiste à écrire un programme, dans n'importe quelle langue, qui ajoute deux nombres à virgule flottante sans utiliser de mathématiques fractionnaires ou à virgule flottante. Les mathématiques entières sont autorisées.

Format

Le format des nombres sont des chaînes contenant des 1 et des 0 qui représentent la valeur binaire d'un flottant 32 bits IEEE 754 . Par exemple, le nombre 2,54 serait représenté par la chaîne "01000000001000101000111101011100".

Objectif

Votre programme doit entrer deux nombres dans le format mentionné ci-dessus, les additionner ensemble et produire le résultat dans le même format. La réponse la plus courte dans n'importe quelle langue gagne!

Règles

Aucune fonction de virgule flottante, décimale ou de type mathématique non entier n'est autorisée.

Vous pouvez supposer que l'entrée est propre (c'est-à-dire qu'elle ne contient que des 1 et des 0).

Vous pouvez supposer que les entrées sont des nombres, et non Inf, -Inf ou NaN ou subnormal. Cependant, si le résultat est supérieur à la valeur max ou inférieur à la valeur min, vous devez renvoyer respectivement Inf et -Inf. Un résultat sous-normal (dénormal) peut être ramené à 0.

Vous n'avez pas à gérer correctement l'arrondi. Ne vous inquiétez pas si vos résultats ne sont pas visibles.

Les tests

Pour tester vos programmes, vous pouvez convertir entre des nombres binaires décimaux et à virgule flottante à l'aide de cet outil .

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

Bonne chance!

Hannesh
la source

Réponses:

3

Python, 224 caractères

Ce code convertit une entrée fà virgule flottante en entier f*2^150, effectue l'ajout à l'aide de grands entiers natifs python, puis reconvertit.

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
la source
3

J (172 caractères)

Étant donné que l'IEEE 754 autorise cinq règles d'arrondi, j'ai choisi la règle "vers 0". Voici mon code:

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

Les mêmes exemples que vous donnez (mais pas exactement les mêmes résultats en raison de la règle d'arrondi différente):

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