floating-point - online - ieee float point
¿Qué idiomas exponen las trampas IEEE 754 al desarrollador? (4)
C y probablemente la mayoría de los lenguajes derivados de él como C ++ o python (aunque puede ser un acceso indirecto). Probablemente sea razonable esperar que los idiomas de bajo nivel tengan dicho soporte.
Ver http://www.math.utah.edu/~beebe/software/ieee/#c-notes que tiene numerosas secuencias de comandos y notas sobre cómo trabajar con números IEEE 754. En particular of1.c se ocupa de las excepciones de coma flotante. Finalmente, de la fuente http://grouper.ieee.org/groups/754/reading.html que incluye un montón de información útil.
Me gustaría jugar con esas trampas con fines educativos.
Un problema común con el comportamiento predeterminado en cálculo numérico es que "extrañamos" el Nan (o + -inf) que apareció en una operación incorrecta. El comportamiento predeterminado es la propagación a través del cálculo, pero algunas operaciones (como las comparaciones) rompen la cadena y sueltan el Nan, y el resto del tratamiento continúa sin reconocer la singularidad en los pasos previos del algoritmo.
A veces tenemos formas de reaccionar ante este tipo de evento: prolongando una función ("0/0 = 12 en mi caso"), o en simulación de dominio de tiempo lanzando el paso e intentando con otras configuraciones (como el predictor, el paso tamaño o lo que sea).
Así que aquí está mi pregunta: ¿conoces los idiomas que exponen las trampas IEEE754 al desarrollador? No tengo ganas de jugar con ASM por eso.
No estoy seguro de cuál es el estándar, pero puedo decirte lo que he visto por experiencia, ya que puede ser útil. He codificado en C ++ y los de NaN son a veces mi peor pesadilla. Aparecen en silencio y se propagan a través del cómputo hasta el final, hasta que tengo salida inútil. A menudo tuve que crear código adicional para detectar específicamente las circunstancias que causan NaN. Estoy usando Visual C ++ 2008, así que espero que siga el estándar IEEE de esta manera.
El lenguaje de programación de Maple tiene un modelo numérico que respeta IEEE-754 y le permite configurar sus propios manejadores de trampa, si lo desea. Aquí hay algunos enlaces:
- Diferencias entre IEEE-754 y los números de Maple (son bastante menores, básicamente solo son nombres de funciones)
- Información general sobre cómputo numérico en Maple
- Información sobre cómo obtener y configurar manejadores de eventos numéricos (el término de Maple para manejadores de trampa)
Una propiedad poco frecuente de Maple es que los números de coma flotante predeterminados son decimales (no binarios) y de precisión arbitraria. Si desea tratar con números de punto flotante binario de 64 bits, envuélvalos en HFloat
. Por ejemplo, 0.2
representa exactamente el número decimal, mientras que HFloat(0.2)
representa el mismo número que obtendría asignando 0.2 a un doble en C. Esto es evidente ejecutando, por ejemplo,
a := HFloat(0.2);
b := 0.2;
evalf[20](a - b);
Esto calcula la diferencia entre a
y b
usando una aritmética de 20 dígitos decimales, y el resultado es 0.11E-16
.
Por lo que yo sé, tiene dos opciones para el manejo de excepciones de coma flotante en C y C ++:
En primer lugar, si deshabilita / enmascara excepciones de coma flotante (que la mayoría de los entornos realizan de forma predeterminada), puede ver si se han producido excepciones de punto flotante al llamar a fetestexcept . fetestexcept no está disponible en Visual C ++, pero puede robar la implementación de MinGW Runtime con la suficiente facilidad. (Es de dominio público). Una vez que se ha marcado una excepción, no se borrará hasta que llame a feclearexcept, por lo que puede llamar a fetestexcept al final de una serie de cálculos para ver si alguno de ellos generó una excepción. Esto no le proporciona las trampas que solicitó, pero le permite probar si se han producido problemas como NaN o +/- inf y reaccionar según sea necesario.
En segundo lugar, puede activar / desactivar las excepciones de coma flotante llamando a feenableexcept en Linux o _controlfp en Windows. La forma en que el sistema operativo maneje una excepción de coma flotante generada por el procesador depende de su sistema operativo.
- En Linux, el sistema operativo envía una señal SIGFPE, por lo que puede instalar un controlador de señal para captar eso y establecer un indicador que le indique a su rutina que reaccione de manera adecuada.
- En Windows, el sistema operativo invoca el Manejo de excepciones estructuradas para convertir la excepción del procesador en una excepción de idioma que puede capturar utilizando un bloque
__try
/__catch
en C otry
/catch
block en C ++. - Actualización: para Mac OS X, como se describe en esta respuesta , debería poder habilitar / desenmascarar excepciones usando
_MM_SET_EXCEPTION_MASK
dexmmintrin.h
, y siempre que use las opciones de compilador predeterminadas (es decir, no deshabilite SSE), usted debería poder detectar excepciones usando SIGFPE.
(He escrito un poco más sobre este y otros problemas de coma flotante en C y C ++ en esta publicación del blog si tienes curiosidad).