(Nota: agregaré 'b' para indicar números binarios aquí. Todos los demás números se dan en decimal)
Una forma de pensar sobre las cosas es en términos de algo como la notación científica. Estamos acostumbrados a ver números expresados en notación científica como, 6.022141 * 10 ^ 23. Los números de coma flotante se almacenan internamente usando un formato similar: mantisa y exponente, pero usando potencias de dos en lugar de diez.
Su 61.0 podría reescribirse como 1.90625 * 2 ^ 5, o 1.11101b * 2 ^ 101b con la mantisa y los exponentes. Para multiplicar eso por diez y (mover el punto decimal), podemos hacer:
(1.90625 * 2 ^ 5) * (1.25 * 2 ^ 3) = (2.3828125 * 2 ^ 8) = (1.19140625 * 2 ^ 9)
o con la mantisa y los exponentes en binario:
(1.11101b * 2 ^ 101b) * (1.01b * 2 ^ 11b) = (10.0110001b * 2 ^ 1000b) = (1.00110001b * 2 ^ 1001b)
Tenga en cuenta lo que hicimos allí para multiplicar los números. Multiplicamos las mantisas y sumamos los exponentes. Luego, dado que la mantisa terminó más de dos, normalizamos el resultado golpeando el exponente. Es como cuando ajustamos el exponente después de hacer una operación con números en notación científica decimal. En cada caso, los valores con los que trabajamos tenían una representación finita en binario, por lo que los valores generados por las operaciones básicas de multiplicación y suma también produjeron valores con una representación finita.
Ahora, considere cómo dividiríamos 61 entre 10. Comenzaríamos dividiendo las mantisas, 1.90625 y 1.25. En decimal, esto da 1.525, un buen número corto. Pero, ¿qué es esto si lo convertimos a binario? Lo haremos de la manera habitual: restando la mayor potencia de dos siempre que sea posible, al igual que convertir decimales enteros en binarios, pero usaremos potencias negativas de dos:
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
0.00009765625 ...
UH oh. Ahora estamos en problemas. Resulta que 1.90625 / 1.25 = 1.525, es una fracción que se repite cuando se expresa en binario: 1.11101b / 1.01b = 1.10000110011 ... b Nuestras máquinas solo tienen tantos bits para contener esa mantisa y así redondearán la fracción y asume ceros más allá de cierto punto. El error que ve cuando divide 61 por 10 es la diferencia entre:
1.100001100110011001100110011001100110011 ... b * 2 ^ 10b
y, digamos:
1.100001100110011001100110b * 2 ^ 10b
Es este redondeo de la mantisa lo que conduce a la pérdida de precisión que asociamos con los valores de coma flotante. Incluso cuando la mantisa se puede expresar exactamente (por ejemplo, al sumar solo dos números), aún podemos obtener una pérdida numérica si la mantisa necesita demasiados dígitos para ajustarse después de normalizar el exponente.
Realmente hacemos este tipo de cosas todo el tiempo cuando redondeamos los números decimales a un tamaño manejable y solo le damos los primeros dígitos. Debido a que expresamos el resultado en decimal, se siente natural. Pero si redondeamos un decimal y luego lo convertimos a una base diferente, se vería tan feo como los decimales que obtenemos debido al redondeo de coma flotante.