errori di virgola mobile in ruby

Qualcuno può spiegare perché moltiplicare per 100 qui dà un risultato meno accurato ma moltiplicando per 10 due volte si ottiene un risultato più accurato?

± % sc Loading development environment (Rails 3.0.1) >> 129.95 * 100 12994.999999999998 >> 129.95*10 1299.5 >> 129.95*10*10 12995.0 

Se esegui i calcoli a mano in binario a precisione doppia, che è limitato a 53 bit significativi, vedrai cosa sta succedendo:

129,95 = 1,0000001111100110011001100110011001100110011001100110 x 2 ^ 7

129,95 * 100 = 1,1100101100001011111111111111111111111111111111111111111011 x 2 ^ 13

Questo è lungo 56 bit significativi, quindi arrotondato a 53 bit è

1.100101100001011111111111111111111111111111111111111111 x 2 ^ 13, che è uguale a

12994,999999999998181010596454143524169921875

Ora 129,95 * 10 = 1.01000100110111111111111111111111111111111111111111111 x 2 ^ 10

Questo è lungo 54 bit significativi, quindi arrotondato a 53 bit è 1.01000100111 x 2 ^ 10 = 1299.5

Ora 1299,5 * 10 = 1,11001011000011 x 2 ^ 13 = 12995.

Prima di tutto: stai guardando la rappresentazione in formato stringa del risultato, non il risultato stesso. Se vuoi davvero confrontare i due risultati, dovresti formattare entrambi i risultati in modo esplicito, usando String#% e dovresti formattare entrambi i risultati allo stesso modo.

In secondo luogo, è così che funzionano i numeri in virgola mobile binari. Sono inesatti, sono finiti e sono binari. Tutti e tre significano che si ottengono errori di arrotondamento, che in genere appaiono del tutto casuali, a meno che non si abbia memorizzato l’intero IEEE754 e si possa recitarlo all’indietro nel sonno.

Non esiste un numero in virgola mobile esattamente uguale a 129.95 . Quindi la tua lingua usa un valore che è vicino ad esso. Quando quel valore è moltiplicato per 100, il risultato è vicino a 12995, ma non è uguale a 12995. (Non è esattamente uguale a 100 volte il valore originale usato al posto di 129.95 ). Quindi il tuo interprete stampa un numero decimale che è vicino (ma non uguale a) al valore di 129.95 * 100 e che mostra che non è esattamente 12995. Si dà anche il caso che il risultato 129.95 * 10 sia esattamente uguale a 1299,5. Questa è principalmente fortuna.

La linea di fondo è, non aspettatevi mai l’uguaglianza da qualsiasi aritmetica in virgola mobile, solo “vicinanza”.