Pregunta

Al escribir algunos casos de prueba, y algunas de las pruebas para comprobar el resultado de un NaN.

He intentado utilizar std::isnan pero los failes de aserción:

Assertion `std::isnan(x)' failed.

Después de imprimir el valor de x, resultó que de negativo NaN (-nan) que es totalmente aceptable en mi caso.

Después de tratar de utilizar el hecho de que NaN != NaN y el uso de assert(x == x), el compilador me hace un 'favor' y optimiza la aserción de distancia.

Haciendo mi propia función isNaN se está optimizando lejos también.

¿Cómo puedo comprobar tanto la igualdad de NaN y -nan?

¿Fue útil?

Solución

Esto es embarazoso.

La razón por la que el compilador (GCC en este caso) ha sido optimizar la comparación de distancia y isnan regresado false fue porque alguien de mi equipo se había convertido en -ffast-math.

A partir de los documentos:

-ffast-math
    Sets -fno-math-errno, -funsafe-math-optimizations,
    -fno-trapping-math, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans and fcx-limited-range.

    This option causes the preprocessor macro __FAST_MATH__ to be defined.

    This option should never be turned on by any -O option since it can result in incorrect output for programs which depend on an exact implementation of IEEE or ISO rules/specifications for math functions. 

Aviso de la frase que termina -. -ffast-math no es seguro

Otros consejos

Se espera que isnan() tener un comportamiento indefinido con -ffast-math.

Esto es lo que yo uso en mi banco de pruebas:

#if defined __FAST_MATH__
#   undef isnan
#endif
#if !defined isnan
#   define isnan isnan
#   include <stdint.h>
static inline int isnan(float f)
{
    union { float f; uint32_t x; } u = { f };
    return (u.x << 1) > 0xff000000u;
}
#endif

Esto parece un error en la ejecución de su biblioteca de isnan() a mí. Trabaja muy bien aquí en gcc 4.2.1 en Snow Leopard. Sin embargo, ¿qué hay de tratar esto?

std::isnan(std::abs(yourNanVariable));

Obviamente, no puedo probarlo, ya que es std::isnan(-NaN) true en mi sistema.

Editar : Con -ffast-math, independientemente del interruptor -O, gcc 4.2.1 en Snow Leopard piensa que es NAN == NAN true, como es NAN == -NAN. Esto podría romper el código de manera catastrófica. Yo le aconsejaría dejando fuera -ffast-math o al menos las pruebas de resultados idénticos en construye utilizando y no usarlo ...

Hay C99 isnan () que debe ser capaz de utilizar.

Si en su aplicación no funciona correctamente (que es eso?) Puede implementar su propia, por reinterpret_casting a largo y haciendo IEEE mordió magia.

Puede comprobar los bits de número. IEEE 754 ha definido máscara para NaN:

  • señalización A NaN está representado por cualquier patrón de bits entre X'7F80 0001' y X'7FBF FFFF 'o entre X'FF80 0001' y X'FFBF FFFF'.
  • A tranquila NaN está representado por cualquier patrón de bits entre X'7FC0 0000' y X'7FFF FFFF 'o entre X'FFC0 0000' y X'FFFF FFFF'.

Esto podría ser no es portátil, pero si está seguro acerca de su platfofm puede ser aceptable. Más: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlf101l.doc/xlfopg/fpieee.htm

Esta está basada en el artículo de wikipedia publicado en los comentarios. Tenga en cuenta que es totalmente no probado -. Debe darle una idea de algo que se puede hacer sin embargo

bool reallyIsNan(float x)
{
    //Assumes sizeof(float) == sizeof(int)
    int intIzedX = *(reinterpret_cast<int *>(&x));
    int clearAllNonNanBits = intIzedX & 0x7F800000;
    return clearAllNonNanBits == 0x7F800000;
}

EDIT:. Realmente creo que debería considerar la presentación de un error con los chicos glibc en que uno, aunque

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top