c++ floating-point precision floating-accuracy ieee-754

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