Aggiunta in virgola mobile, senza galleggianti!


9

Il tuo compito è quello di scrivere un programma, in qualsiasi lingua, che sommi due numeri in virgola mobile SENZA utilizzare qualsiasi matematica frazionaria o in virgola mobile. La matematica integer è consentita.

Formato

Il formato per i numeri sono stringhe contenenti 1 e 0 che rappresentano il valore binario di un float IEEE 754 a 32 bit . Ad esempio il numero 2.54 sarebbe rappresentato dalla stringa "01000000001000101000111101011100".

Obbiettivo

Il programma dovrebbe inserire due numeri nel formato sopra menzionato, aggiungerli insieme e produrre il risultato nello stesso formato. Vince la risposta più breve in qualsiasi lingua!

Regole

Non sono assolutamente consentite funzioni matematiche a virgola mobile, decimale o qualsiasi tipo non intero.

Si può presumere che l'ingresso sia pulito (cioè contiene solo 1 e 0).

Si può presumere che gli ingressi siano numeri e non Inf, -Inf o NaN o subnormali. Tuttavia, se il risultato è maggiore del valore massimo o inferiore al valore minimo, è necessario restituire rispettivamente Inf e -Inf. Un risultato non normale (denormale) può essere portato a 0.

Non è necessario gestire l'arrotondamento correttamente. Non preoccuparti se i risultati sono pochi.

test

Per testare i tuoi programmi, puoi convertire tra numeri binari decimali e in virgola mobile usando questo strumento .

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

In bocca al lupo!

Risposte:


3

Python, 224 caratteri

Questo codice converte un input fin virgola mobile nell'intero f*2^150, esegue l'aggiunta utilizzando interi grandi nativi di Python, quindi converte indietro.

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 caratteri)

Poiché IEEE 754 consente cinque regole di arrotondamento, ho scelto la regola "verso 0". Ecco il mio codice:

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

Gli stessi esempi che dai (ma non esattamente gli stessi risultati a causa della diversa regola di arrotondamento):

   '01000100011110100000000000000000' a '00111111000000000000000000000000'
01000100011110100010000000000000
   '01111111011111111111111111111111' a '01111111011111111111111111111111'
01111111100000000000000000000000
   '01000011101000001000111110111110' a '11000010111101101010010001011010'
01000011010001011100110101001111
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.