resueltos que punto online numericos notación normalizada norma metodos mantisa informatica flotante ejercicios ejemplos coma c 64bit floating-point

que - Precisión de punto flotante al pasar de i386 a x86_64



punto flotante metodos numericos (4)

El punto flotante SSE y el punto flotante 387 usan instrucciones completamente diferentes, por lo que no hay forma de convencer a las instrucciones SSE fp para usar el 387. Probablemente la mejor manera de lidiar con esto es renunciar a su conjunto de pruebas para obtener resultados ligeramente diferentes y no depender los resultados son los mismos que en el último bit.

Tengo una aplicación que fue desarrollada para Linux x86 de 32 bits. Hay muchas operaciones de punto flotante y muchas pruebas según los resultados. Ahora lo estamos portando a x86_64, pero los resultados de las pruebas son diferentes en esta arquitectura. No queremos mantener un conjunto separado de resultados para cada arquitectura.

Según el artículo Introducción a GCC, para los compiladores de GNU gcc y g ++, el problema es que GCC en X86_64 supone fpmath = sse, mientras que x86 supone fpmath = 387 . El 387 FPU usa precisión interna de 80 bits para todas las operaciones y solo convierte el resultado a un tipo de punto flotante dado (flotante, doble o doble largo) mientras que SSE usa el tipo de operandos para determinar su precisión interna.

Puedo forzar -mfpmath = 387 cuando compilo mi propio código y todas mis operaciones funcionan correctamente, pero cada vez que llamo a alguna función de biblioteca (sin, cos, atan2, etc.) los resultados son incorrectos nuevamente. Supongo que es porque se compiló libm sin la anulación fpmath.

Traté de construir libm yo mismo (glibc) usando la emulación 387, pero causó muchos bloqueos (no sé si hice algo mal).

¿Hay alguna manera de forzar a todos los códigos en un proceso a usar la emulación 387 en x86_64? ¿O tal vez alguna biblioteca que devuelva los mismos valores que libm en ambas arquitecturas? ¿Alguna sugerencia?

Con respecto a la pregunta "¿Necesita la precisión de 80 bits?", Debo decir que esto no es un problema para una operación individual. En este caso simple, la diferencia es realmente pequeña y no hace diferencia. Sin embargo, cuando se combinan muchas operaciones, el error se propaga y la diferencia en el resultado final ya no es tan pequeña y hace la diferencia. Así que supongo que necesito la precisión de 80 bits.


Yo diría que necesitas arreglar tus pruebas. En general, te estás preparando para la desilusión si asumes que las matemáticas de coma flotante son precisas. En lugar de probar la igualdad exacta , pruebe si está lo suficientemente cerca del resultado esperado. Lo que has encontrado no es un error, después de todo, así que si tus pruebas informan de errores, las pruebas son incorrectas. ;)

Como ha descubierto, cada biblioteca en la que confíe asumirá coma flotante SSE, por lo tanto, a menos que planee compilar todo de forma manual, ahora y para siempre, para que pueda configurar el modo FP en x87, es mejor que no trate con el problema ahora, y simplemente aceptando que las matemáticas FP no son 100% precisas, y en general no arrojarán el mismo resultado en dos plataformas diferentes. (Creo que el rendimiento de la CPU AMD es ligeramente diferente en matemáticas x87 también).

¿ Necesitas absolutamente precisión de 80 bits? (De ser así, obviamente no hay muchas alternativas, aparte de compilar todo para usar FP de 80 bits).

De lo contrario, ajuste sus pruebas para realizar comparaciones y pruebas de igualdad dentro de un épsilon pequeño. Si la diferencia es menor que épsilon, los valores se consideran iguales.


La precisión de 80 bits es realmente peligrosa. El problema es que en realidad se conserva mientras la variable esté almacenada en el registro de la CPU. Cada vez que se fuerza a la RAM, se trunca al tipo de precisión. Entonces puede tener una variable que realmente cambie su valor aunque no le haya pasado nada en el código.


Si desea long double precisión long double , use el long double para todas sus variables de punto flotante, en lugar de esperar que el float o el double tengan una precisión mágica adicional. Esto es realmente una obviedad.