/** Generate NaN. @return Floating-point representation of NaN. */ TRIO_PUBLIC double trio_nan(void) { /* Cache the result */ static double result = 0.0; if (result == 0.0) { #if defined(TRIO_COMPILER_SUPPORTS_C99) result = nan(NULL); #elif defined(NAN) && defined(__STDC_IEC_559__) result = (double)NAN; #elif defined(USE_IEEE_754) result = trio_make_double(ieee_754_qnan_array); #else /* * There are several ways to generate NaN. The one used here is * to divide infinity by infinity. I would have preferred to add * negative infinity to positive infinity, but that yields wrong * result (infinity) on FreeBSD. * * This may fail if the hardware does not support NaN, or if * the Invalid Operation floating-point exception is unmasked. */ # if defined(TRIO_PLATFORM_UNIX) void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); # endif result = trio_pinf() / trio_pinf(); # if defined(TRIO_PLATFORM_UNIX) signal(SIGFPE, signal_handler); # endif #endif } return result; }
/************************************************************************* * trio_pinf */ TRIO_PUBLIC double trio_pinf(void) { /* Cache the result */ static double result = 0.0; if (result == 0.0) { #if defined(INFINITY) && defined(__STDC_IEC_559__) result = (double)INFINITY; #elif defined(USE_IEEE_754) result = trio_make_double(ieee_754_infinity_array); #else /* * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used * as infinity. Otherwise we have to resort to an overflow * operation to generate infinity. */ # if defined(TRIO_PLATFORM_UNIX) void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); # endif result = HUGE_VAL; if (HUGE_VAL == DBL_MAX) { /* Force overflow */ result += HUGE_VAL; } # if defined(TRIO_PLATFORM_UNIX) signal(SIGFPE, signal_handler); # endif #endif } return result; }