(Nota: aggiungerò 'b' per indicare i numeri binari qui. Tutti gli altri numeri sono indicati in decimali)
Un modo di pensare alle cose è in termini di qualcosa come la notazione scientifica. Siamo abituati a vedere numeri espressi in notazione scientifica come 6.022141 * 10 ^ 23. I numeri in virgola mobile sono memorizzati internamente usando un formato simile - mantissa ed esponente, ma usando potenze di due invece di dieci.
Il tuo 61.0 potrebbe essere riscritto come 1.90625 * 2 ^ 5 o 1.11101b * 2 ^ 101b con la mantissa e gli esponenti. Per moltiplicarlo per dieci e (spostare il punto decimale), possiamo fare:
(1.90625 * 2 ^ 5) * (1.25 * 2 ^ 3) = (2.3828125 * 2 ^ 8) = (1.19140625 * 2 ^ 9)
o dentro con la mantissa e gli esponenti in binario:
(1.11101b * 2 ^ 101b) * (1.01b * 2 ^ 11b) = (10.0110001b * 2 ^ 1000b) = (1.00110001b * 2 ^ 1001b)
Nota cosa abbiamo fatto lì per moltiplicare i numeri. Abbiamo moltiplicato le mantisse e aggiunto gli esponenti. Quindi, poiché la mantissa finiva più di due, abbiamo normalizzato il risultato urtando l'esponente. È proprio come quando regoliamo l'esponente dopo aver fatto un'operazione sui numeri in notazione scientifica decimale. In ogni caso, i valori con cui abbiamo lavorato avevano una rappresentazione finita in binario, quindi i valori emessi dalle operazioni di moltiplicazione e addizione di base producevano anche valori con una rappresentazione finita.
Ora, considera come divideremo 61 per 10. Iniziamo dividendo le mante, 1.90625 e 1.25. In decimale, questo dà 1,525, un bel numero breve. Ma cos'è questo se lo convertiamo in binario? Lo faremo nel solito modo - sottraendo la più grande potenza di due quando possibile, proprio come convertire i decimali di numeri interi in binario, ma useremo i poteri negativi di due:
1.525 - 1 * 2 ^ 0 -> 1
0,525 - 1 * 2 ^ -1 -> 1
0,025 - 0 * 2 ^ -2 -> 0
0,025 - 0 * 2 ^ -3 -> 0
0,025 - 0 * 2 ^ -4 -> 0
0,025 - 0 * 2 ^ -5 -> 0
0,025 - 1 * 2 ^ -6 -> 1
0,009375 - 1 * 2 ^ -7 -> 1
0,0015625 - 0 * 2 ^ -8 -> 0
0,0015625 - 0 * 2 ^ -9 -> 0
0,0015625 - 1 * 2 ^ -10 -> 1
0.0005859375 - 1 * 2 ^ -11 -> 1
,00009765625 ...
Uh Oh. Ora siamo nei guai. Si scopre che 1.90625 / 1.25 = 1.525, è una frazione ripetitiva quando espressa in binario: 1.11101b / 1.01b = 1.10000110011 ... b Le nostre macchine hanno solo così tanti bit per contenere quella mantissa e quindi arrotondano solo la frazione e assumere zero oltre un certo punto. L'errore che vedi quando dividi 61 per 10 è la differenza tra:
1.100001100110011001100110011001100110011 ... b * 2 ^ 10b
e, diciamo:
1.100001100110011001100110b * 2 ^ 10b
È questo arrotondamento della mantissa che porta alla perdita di precisione che associamo ai valori in virgola mobile. Anche quando la mantissa può essere espressa esattamente (ad esempio, quando si aggiungono solo due numeri), possiamo comunque ottenere una perdita numerica se la mantissa necessita di troppe cifre per adattarsi dopo la normalizzazione dell'esponente.
In realtà facciamo questo genere di cose tutto il tempo quando arrotondiamo i numeri decimali a una dimensione gestibile e ne forniamo solo le prime cifre. Poiché esprimiamo il risultato in decimale, sembra naturale. Ma se arrotondassimo un decimale e lo convertissimo in una base diversa, sembrerebbe brutto quanto i decimali che otteniamo a causa dell'arrotondamento in virgola mobile.