Gleitkomma-Addition ohne Schwimmer!

9

Ihre Aufgabe ist es, ein Programm in einer beliebigen Sprache zu schreiben, das zwei Gleitkommazahlen ohne Verwendung von Bruch- oder Gleitkomma-Mathematik addiert . Ganzzahlige Mathematik ist erlaubt.

Format

Das Format für die Zahlen sind Zeichenfolgen mit Einsen und Nullen, die den Binärwert eines IEEE 754 32-Bit-Floats darstellen . Zum Beispiel würde die Nummer 2.54 durch die Zeichenfolge "01000000001000101000111101011100" dargestellt.

Tor

Ihr Programm sollte zwei Zahlen im oben genannten Format eingeben, addieren und das Ergebnis im gleichen Format ausgeben. Die kürzeste Antwort in einer Sprache gewinnt!

Regeln

Es sind absolut keine Gleitkomma-, Dezimal- oder nicht ganzzahligen mathematischen Funktionen zulässig.

Sie können davon ausgehen, dass die Eingabe sauber ist (dh nur Einsen und Nullen enthält).

Sie können davon ausgehen, dass die Eingaben Zahlen sind und nicht Inf, -Inf oder NaN oder subnormal. Wenn das Ergebnis jedoch größer als der Maximalwert oder kleiner als der Minimalwert ist, sollten Sie Inf bzw. -Inf zurückgeben. Ein subnormales (denormales) Ergebnis kann auf 0 gespült werden.

Sie müssen nicht richtig mit Rundungen umgehen. Machen Sie sich keine Sorgen, wenn Ihre Ergebnisse ein paar Punkte entfernt sind.

Tests

Um Ihre Programme zu testen, können Sie mit diesem Tool zwischen Dezimal- und Gleitkomma-Binärzahlen konvertieren .

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

Viel Glück!

Hannesh
quelle

Antworten:

3

Python, 224 Zeichen

Dieser Code konvertiert eine Gleitkomma-Eingabe fin die Ganzzahl f*2^150, addiert sie mit nativen großen Python-Ganzzahlen und konvertiert sie dann zurück.

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

J (172 Zeichen)

Da IEEE 754 fünf Rundungsregeln zulässt, habe ich die Regel "gegen 0" gewählt. Hier ist mein Code:

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

Dieselben Beispiele, die Sie geben (aber aufgrund der unterschiedlichen Rundungsregel nicht genau dieselben Ergebnisse):

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