ReactOS 0.4.15-dev-7953-g1f49173
SpecialQuantities

Macros

#define TRIO_TRUE   (1 == 1)
 
#define TRIO_FALSE   (0 == 1)
 

Functions

TRIO_PUBLIC double trio_nzero (TRIO_NOARGS)
 
TRIO_PUBLIC double trio_pinf (TRIO_NOARGS)
 
TRIO_PUBLIC double trio_ninf (TRIO_NOARGS)
 
TRIO_PUBLIC double trio_nan (TRIO_NOARGS)
 
TRIO_PUBLIC int trio_isnan TRIO_ARGS1 ((number), double number)
 
TRIO_PUBLIC int trio_fpclassify_and_signbit TRIO_ARGS2 ((number, is_negative), double number, int *is_negative)
 

Variables

static TRIO_CONST char rcsid [] = "@(#)$Id$"
 

Detailed Description

Macro Definition Documentation

◆ TRIO_FALSE

#define TRIO_FALSE   (0 == 1)

Definition at line 74 of file trionan.c.

◆ TRIO_TRUE

#define TRIO_TRUE   (1 == 1)

Definition at line 73 of file trionan.c.

Function Documentation

◆ TRIO_ARGS1()

TRIO_PUBLIC int trio_signbit TRIO_ARGS1 ( (number ,
double  number 
)

Check for NaN.

Parameters
numberAn arbitrary floating-point number.
Returns
Boolean value indicating whether or not the number is a NaN.

Check for infinity.

Parameters
numberAn arbitrary floating-point number.
Returns
1 if positive infinity, -1 if negative infinity, 0 otherwise.

Examine the sign of a number.

Parameters
numberAn arbitrary floating-point number.
Returns
Boolean value indicating whether or not the number has the sign bit set (i.e. is negative).

Definition at line 372 of file trionan.c.

374{
375#if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \
376 || defined(TRIO_COMPILER_SUPPORTS_UNIX95)
377 /*
378 * C99 defines isnan() as a macro. UNIX95 defines isnan() as a
379 * function. This function was already present in XPG4, but this
380 * is a bit tricky to detect with compiler defines, so we choose
381 * the conservative approach and only use it for UNIX95.
382 */
383 return isnan(number);
384
385#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
386 /*
387 * Microsoft Visual C++ and Borland C++ Builder have an _isnan()
388 * function.
389 */
390 return _isnan(number) ? TRIO_TRUE : TRIO_FALSE;
391
392#elif defined(USE_IEEE_754)
393 /*
394 * Examine IEEE 754 bit-pattern. A NaN must have a special exponent
395 * pattern, and a non-empty mantissa.
396 */
397 int has_mantissa;
398 int is_special_quantity;
399
400 is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
401
402 return (is_special_quantity && has_mantissa);
403
404#else
405 /*
406 * Fallback solution
407 */
408 int status;
409 double integral, fraction;
410
411# if defined(TRIO_PLATFORM_UNIX)
412 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
413# endif
414
415 status = (/*
416 * NaN is the only number which does not compare to itself
417 */
419 /*
420 * Fallback solution if NaN compares to NaN
421 */
422 ((number != 0.0) &&
423 (fraction = modf(number, &integral),
424 integral == fraction)));
425
426# if defined(TRIO_PLATFORM_UNIX)
427 signal(SIGFPE, signal_handler);
428# endif
429
430 return status;
431
432#endif
433}
#define SIGFPE
Definition: signal.h:30
#define SIG_IGN
Definition: signal.h:48
#define TRIO_VOLATILE
Definition: triodef.h:130
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define TRIO_TRUE
Definition: trionan.c:73
#define TRIO_FALSE
Definition: trionan.c:74
_Check_return_ __MINGW_NOTHROW _CRTIMP int __cdecl _isnan(_In_ double)
_Check_return_ _CRTIMP double __cdecl modf(_In_ double x, _Out_ double *y)
#define isnan(x)
Definition: mingw_math.h:133
static unsigned int number
Definition: dsound.c:1479
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
int signal
Definition: except.c:82
Definition: ps.c:97

◆ TRIO_ARGS2()

TRIO_PUBLIC int trio_fpclassify_and_signbit TRIO_ARGS2 ( (number, is_negative)  ,
double  number,
int is_negative 
)

Definition at line 561 of file trionan.c.

564{
565#if defined(fpclassify) && defined(signbit)
566 /*
567 * C99 defines fpclassify() and signbit() as a macros
568 */
569 *is_negative = signbit(number);
570 switch (fpclassify(number)) {
571 case FP_NAN:
572 return TRIO_FP_NAN;
573 case FP_INFINITE:
574 return TRIO_FP_INFINITE;
575 case FP_SUBNORMAL:
576 return TRIO_FP_SUBNORMAL;
577 case FP_ZERO:
578 return TRIO_FP_ZERO;
579 default:
580 return TRIO_FP_NORMAL;
581 }
582
583#else
584# if defined(TRIO_COMPILER_DECC)
585 /*
586 * DECC has an fp_class() function.
587 */
588# define TRIO_FPCLASSIFY(n) fp_class(n)
589# define TRIO_QUIET_NAN FP_QNAN
590# define TRIO_SIGNALLING_NAN FP_SNAN
591# define TRIO_POSITIVE_INFINITY FP_POS_INF
592# define TRIO_NEGATIVE_INFINITY FP_NEG_INF
593# define TRIO_POSITIVE_SUBNORMAL FP_POS_DENORM
594# define TRIO_NEGATIVE_SUBNORMAL FP_NEG_DENORM
595# define TRIO_POSITIVE_ZERO FP_POS_ZERO
596# define TRIO_NEGATIVE_ZERO FP_NEG_ZERO
597# define TRIO_POSITIVE_NORMAL FP_POS_NORM
598# define TRIO_NEGATIVE_NORMAL FP_NEG_NORM
599
600# elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
601 /*
602 * Microsoft Visual C++ and Borland C++ Builder have an _fpclass()
603 * function.
604 */
605# define TRIO_FPCLASSIFY(n) _fpclass(n)
606# define TRIO_QUIET_NAN _FPCLASS_QNAN
607# define TRIO_SIGNALLING_NAN _FPCLASS_SNAN
608# define TRIO_POSITIVE_INFINITY _FPCLASS_PINF
609# define TRIO_NEGATIVE_INFINITY _FPCLASS_NINF
610# define TRIO_POSITIVE_SUBNORMAL _FPCLASS_PD
611# define TRIO_NEGATIVE_SUBNORMAL _FPCLASS_ND
612# define TRIO_POSITIVE_ZERO _FPCLASS_PZ
613# define TRIO_NEGATIVE_ZERO _FPCLASS_NZ
614# define TRIO_POSITIVE_NORMAL _FPCLASS_PN
615# define TRIO_NEGATIVE_NORMAL _FPCLASS_NN
616
617# elif defined(FP_PLUS_NORM)
618 /*
619 * HP-UX 9.x and 10.x have an fpclassify() function, that is different
620 * from the C99 fpclassify() macro supported on HP-UX 11.x.
621 *
622 * AIX has class() for C, and _class() for C++, which returns the
623 * same values as the HP-UX fpclassify() function.
624 */
625# if defined(TRIO_PLATFORM_AIX)
626# if defined(__cplusplus)
627# define TRIO_FPCLASSIFY(n) _class(n)
628# else
629# define TRIO_FPCLASSIFY(n) class(n)
630# endif
631# else
632# define TRIO_FPCLASSIFY(n) fpclassify(n)
633# endif
634# define TRIO_QUIET_NAN FP_QNAN
635# define TRIO_SIGNALLING_NAN FP_SNAN
636# define TRIO_POSITIVE_INFINITY FP_PLUS_INF
637# define TRIO_NEGATIVE_INFINITY FP_MINUS_INF
638# define TRIO_POSITIVE_SUBNORMAL FP_PLUS_DENORM
639# define TRIO_NEGATIVE_SUBNORMAL FP_MINUS_DENORM
640# define TRIO_POSITIVE_ZERO FP_PLUS_ZERO
641# define TRIO_NEGATIVE_ZERO FP_MINUS_ZERO
642# define TRIO_POSITIVE_NORMAL FP_PLUS_NORM
643# define TRIO_NEGATIVE_NORMAL FP_MINUS_NORM
644# endif
645
646# if defined(TRIO_FPCLASSIFY)
647 switch (TRIO_FPCLASSIFY(number)) {
648 case TRIO_QUIET_NAN:
649 case TRIO_SIGNALLING_NAN:
650 *is_negative = TRIO_FALSE; /* NaN has no sign */
651 return TRIO_FP_NAN;
652 case TRIO_POSITIVE_INFINITY:
653 *is_negative = TRIO_FALSE;
654 return TRIO_FP_INFINITE;
655 case TRIO_NEGATIVE_INFINITY:
656 *is_negative = TRIO_TRUE;
657 return TRIO_FP_INFINITE;
658 case TRIO_POSITIVE_SUBNORMAL:
659 *is_negative = TRIO_FALSE;
660 return TRIO_FP_SUBNORMAL;
661 case TRIO_NEGATIVE_SUBNORMAL:
662 *is_negative = TRIO_TRUE;
663 return TRIO_FP_SUBNORMAL;
664 case TRIO_POSITIVE_ZERO:
665 *is_negative = TRIO_FALSE;
666 return TRIO_FP_ZERO;
667 case TRIO_NEGATIVE_ZERO:
668 *is_negative = TRIO_TRUE;
669 return TRIO_FP_ZERO;
670 case TRIO_POSITIVE_NORMAL:
671 *is_negative = TRIO_FALSE;
672 return TRIO_FP_NORMAL;
673 case TRIO_NEGATIVE_NORMAL:
674 *is_negative = TRIO_TRUE;
675 return TRIO_FP_NORMAL;
676 default:
677 /* Just in case... */
678 *is_negative = (number < 0.0);
679 return TRIO_FP_NORMAL;
680 }
681
682# else
683 /*
684 * Fallback solution.
685 */
686 int rc;
687
688 if (number == 0.0) {
689 /*
690 * In IEEE 754 the sign of zero is ignored in comparisons, so we
691 * have to handle this as a special case by examining the sign bit
692 * directly.
693 */
694# if defined(USE_IEEE_754)
695 *is_negative = trio_is_negative(number);
696# else
697 *is_negative = TRIO_FALSE; /* FIXME */
698# endif
699 return TRIO_FP_ZERO;
700 }
701 if (trio_isnan(number)) {
702 *is_negative = TRIO_FALSE;
703 return TRIO_FP_NAN;
704 }
705 if ((rc = trio_isinf(number))) {
706 *is_negative = (rc == -1);
707 return TRIO_FP_INFINITE;
708 }
709 if ((number > 0.0) && (number < DBL_MIN)) {
710 *is_negative = TRIO_FALSE;
711 return TRIO_FP_SUBNORMAL;
712 }
713 if ((number < 0.0) && (number > -DBL_MIN)) {
714 *is_negative = TRIO_TRUE;
715 return TRIO_FP_SUBNORMAL;
716 }
717 *is_negative = (number < 0.0);
718 return TRIO_FP_NORMAL;
719
720# endif
721#endif
722}
#define DBL_MIN
Definition: gcc_float.h:125
#define FP_NAN
Definition: math.h:68
#define FP_ZERO
Definition: math.h:71
#define FP_INFINITE
Definition: math.h:67
#define FP_SUBNORMAL
Definition: math.h:70
#define fpclassify(x)
Definition: mingw_math.h:86
#define signbit(x)
Definition: mingw_math.h:164
@ TRIO_FP_ZERO
Definition: trionan.h:32
@ TRIO_FP_SUBNORMAL
Definition: trionan.h:31
@ TRIO_FP_NAN
Definition: trionan.h:29
@ TRIO_FP_INFINITE
Definition: trionan.h:28
@ TRIO_FP_NORMAL
Definition: trionan.h:30

◆ trio_nan()

TRIO_PUBLIC double trio_nan ( TRIO_NOARGS  )

Generate NaN.

Returns
Floating-point representation of NaN.

Definition at line 323 of file trionan.c.

324{
325 /* Cache the result */
326 static double result = 0.0;
327
328 if (result == 0.0) {
329
330#if defined(TRIO_COMPILER_SUPPORTS_C99) && (!defined(__REACTOS__) || !defined(__clang__))
331 result = nan("");
332
333#elif defined(NAN) && defined(__STDC_IEC_559__)
334 result = (double)NAN;
335
336#elif defined(USE_IEEE_754)
337 result = trio_make_double(ieee_754_qnan_array);
338
339#else
340 /*
341 * There are several ways to generate NaN. The one used here is
342 * to divide infinity by infinity. I would have preferred to add
343 * negative infinity to positive infinity, but that yields wrong
344 * result (infinity) on FreeBSD.
345 *
346 * This may fail if the hardware does not support NaN, or if
347 * the Invalid Operation floating-point exception is unmasked.
348 */
349# if defined(TRIO_PLATFORM_UNIX)
350 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
351# endif
352
353 result = trio_pinf() / trio_pinf();
354
355# if defined(TRIO_PLATFORM_UNIX)
356 signal(SIGFPE, signal_handler);
357# endif
358
359#endif
360 }
361 return result;
362}
GLuint64EXT * result
Definition: glext.h:11304
TRIO_PUBLIC double trio_pinf(TRIO_NOARGS)
Definition: trionan.c:258
double __cdecl nan(const char *tagp)
#define NAN
Definition: mesh.c:39

◆ trio_ninf()

TRIO_PUBLIC double trio_ninf ( TRIO_NOARGS  )

Generate negative infinity.

Returns
Floating-point value of negative infinity.

Definition at line 302 of file trionan.c.

303{
304 static double result = 0.0;
305
306 if (result == 0.0) {
307 /*
308 * Negative infinity is calculated by negating positive infinity,
309 * which can be done because it is legal to do calculations on
310 * infinity (for example, 1 / infinity == 0).
311 */
312 result = -trio_pinf();
313 }
314 return result;
315}

◆ trio_nzero()

TRIO_PUBLIC double trio_nzero ( TRIO_NOARGS  )

Generate negative zero.

Returns
Floating-point representation of negative zero.

Definition at line 241 of file trionan.c.

242{
243#if defined(USE_IEEE_754)
244 return trio_make_double(ieee_754_negzero_array);
245#else
246 TRIO_VOLATILE double zero = 0.0;
247
248 return -zero;
249#endif
250}
int zero
Definition: sehframes.cpp:29

◆ trio_pinf()

TRIO_PUBLIC double trio_pinf ( TRIO_NOARGS  )

Generate positive infinity.

Returns
Floating-point representation of positive infinity.

Definition at line 258 of file trionan.c.

259{
260 /* Cache the result */
261 static double result = 0.0;
262
263 if (result == 0.0) {
264
265#if defined(INFINITY) && defined(__STDC_IEC_559__)
267
268#elif defined(USE_IEEE_754)
269 result = trio_make_double(ieee_754_infinity_array);
270
271#else
272 /*
273 * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used
274 * as infinity. Otherwise we have to resort to an overflow
275 * operation to generate infinity.
276 */
277# if defined(TRIO_PLATFORM_UNIX)
278 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
279# endif
280
282 if (HUGE_VAL == DBL_MAX) {
283 /* Force overflow */
284 result += HUGE_VAL;
285 }
286
287# if defined(TRIO_PLATFORM_UNIX)
288 signal(SIGFPE, signal_handler);
289# endif
290
291#endif
292 }
293 return result;
294}
#define DBL_MAX
Definition: gcc_float.h:108
#define HUGE_VAL
Definition: math.h:51
#define INFINITY
Definition: misc.c:36

Referenced by trio_nan(), and trio_ninf().

Variable Documentation

◆ rcsid

TRIO_CONST char rcsid[] = "@(#)$Id$"
static

Definition at line 115 of file trionan.c.