c++ - Invertibilidad de la división de punto flotante IEEE 754
floating-point precision (2)
Obviamente no. 1/10 no tiene representación. Obtienes una aproximación en su lugar. Invertir eso no te dará 10.
Edición: hay un gran número de estos. Cualquier inverso que requiera más de 53 bits será uno de ellos.
Hay una prueba fácil. En C podrías probar 1.0 / (1.0 / 10.0) contra 10.0 y descubrirás que no son iguales.
¿Cuál es la invertibilidad de la división de punto flotante IEEE 754? Quiero decir, ¿está garantizado por el estándar que si double y = 1.0 / x
entonces x == 1.0 / y
, es decir, x
puede restaurarse poco a poco?
Los casos en que y
es infinity
o NaN
son excepciones obvias.
Sí, hay valores de IEEE 754 de doble precisión (*) x
que son tales x != 1.0 / (1.0 / x)
.
Es fácil construir un ejemplo de un valor normal con esta propiedad a mano: el que se escribe 0x1.fffffffffffffp0
en la notación hexadecimal de C99 para valores de punto flotante es tal que 1.0 / (1.0 / 0x1.fffffffffffffp0) == 0x1.ffffffffffffep0
. Era natural esperar que 0x1.fffffffffffffp0
sea un contraejemplo porque 1.0 / 0x1.fffffffffffffp0
cae al comienzo de un binade, donde los números de punto flotante son menos densos, por lo que tuvo que ocurrir un error relativo mayor en la división más interna. Más precisamente, 1.0 / 0x1.fffffffffffffp0
cae justo por encima del punto medio entre 0.5
y su sucesor de doble precisión, de modo que 1.0 / 0x1.fffffffffffffp0
se redondea al sucesor de 0.5, con un gran error relativo.
En formato decimal %.16e
, 0x1.fffffffffffffp0
es 1.9999999999999998e+00
y 0x1.ffffffffffffep0
es 1.9999999999999996e+00
.
(*) no hay ninguna razón para que la función inversa tenga la propiedad en la pregunta para ninguno de los formatos IEEE 754