aboutsummaryrefslogtreecommitdiffstats
path: root/trio/trionan.c
diff options
context:
space:
mode:
authorMatthias Andree <matthias.andree@gmx.de>2009-07-02 19:48:34 +0000
committerMatthias Andree <matthias.andree@gmx.de>2009-07-02 19:48:34 +0000
commitc8e1897c969ce43b551c29d65bc605f175c01263 (patch)
treed976ad001b090dbebd5ee58a4929108de7ce426d /trio/trionan.c
parent33c48f99e8b28504cc68a9bd672e487422602038 (diff)
downloadfetchmail-c8e1897c969ce43b551c29d65bc605f175c01263.tar.gz
fetchmail-c8e1897c969ce43b551c29d65bc605f175c01263.tar.bz2
fetchmail-c8e1897c969ce43b551c29d65bc605f175c01263.zip
Update trio to CVS checkout of 2009-07-02.
svn path=/branches/BRANCH_6-3/; revision=5370
Diffstat (limited to 'trio/trionan.c')
-rw-r--r--trio/trionan.c1112
1 files changed, 734 insertions, 378 deletions
diff --git a/trio/trionan.c b/trio/trionan.c
index 4391477e..30163225 100644
--- a/trio/trionan.c
+++ b/trio/trionan.c
@@ -1,6 +1,6 @@
/*************************************************************************
*
- * $Id: trionan.c,v 1.26 2002/12/08 12:08:21 breese Exp $
+ * $Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $
*
* Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
*
@@ -31,12 +31,6 @@
*
************************************************************************/
-/*
- * TODO:
- * o Put all the magic into trio_fpclassify_and_signbit(), and use this from
- * trio_isnan() etc.
- */
-
/*************************************************************************
* Include files
*/
@@ -46,7 +40,9 @@
#include <math.h>
#include <string.h>
#include <limits.h>
-#include <float.h>
+#if !defined(TRIO_PLATFORM_SYMBIAN)
+# include <float.h>
+#endif
#if defined(TRIO_PLATFORM_UNIX)
# include <signal.h>
#endif
@@ -66,6 +62,13 @@
* Definitions
*/
+#if !defined(TRIO_PUBLIC_NAN)
+# define TRIO_PUBLIC_NAN TRIO_PUBLIC
+#endif
+#if !defined(TRIO_PRIVATE_NAN)
+# define TRIO_PRIVATE_NAN TRIO_PRIVATE
+#endif
+
#define TRIO_TRUE (1 == 1)
#define TRIO_FALSE (0 == 1)
@@ -81,8 +84,10 @@
# error "Must be compiled with option -ieee"
# endif
# endif
-# elif defined(TRIO_COMPILER_GCC) && (defined(__osf__) || defined(__linux__))
-# error "Must be compiled with option -mieee"
+# else
+# if defined(TRIO_COMPILER_GCC)
+# error "Must be compiled with option -mieee"
+# endif
# endif
#endif /* __alpha && ! _IEEE_FP */
@@ -99,19 +104,135 @@
* implicitly (the so-called "hidden bit"), which leaves us with
* the ability to represent 53 bits wide mantissa.
*/
-#if (FLT_RADIX == 2) && (DBL_MAX_EXP == 1024) && (DBL_MANT_DIG == 53)
-# define USE_IEEE_754
+#if defined(__STDC_IEC_559__)
+# define TRIO_IEEE_754
+#else
+# if (FLT_RADIX - 0 == 2) && (DBL_MAX_EXP - 0 == 1024) && (DBL_MANT_DIG - 0 == 53)
+# define TRIO_IEEE_754
+# endif
+#endif
+
+/*
+ * Determine which fpclassify_and_sign() function to use.
+ */
+#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
+# if defined(PREDEF_STANDARD_C99) && defined(fpclassify)
+# define TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT
+# else
+# if defined(TRIO_COMPILER_DECC)
+# define TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT
+# else
+# if defined(TRIO_COMPILER_VISUALC) || defined(TRIO_COMPILER_BORLAND)
+# define TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT
+# else
+# if defined(TRIO_COMPILER_HP) && defined(FP_PLUS_NORM)
+# define TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT
+# else
+# if defined(TRIO_COMPILER_XLC) && defined(FP_PLUS_NORM)
+# define TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT
+# else
+# define TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT
+# endif
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/*
+ * Determine how to generate negative zero.
+ */
+#if defined(TRIO_FUNC_NZERO)
+# if defined(TRIO_IEEE_754)
+# define TRIO_NZERO_IEEE_754
+# else
+# define TRIO_NZERO_FALLBACK
+# endif
+#endif
+
+/*
+ * Determine how to generate positive infinity.
+ */
+#if defined(TRIO_FUNC_PINF)
+# if defined(INFINITY) && defined(__STDC_IEC_559__)
+# define TRIO_PINF_C99_MACRO
+# else
+# if defined(TRIO_IEEE_754)
+# define TRIO_PINF_IEEE_754
+# else
+# define TRIO_PINF_FALLBACK
+# endif
+# endif
+#endif
+
+/*
+ * Determine how to generate NaN.
+ */
+#if defined(TRIO_FUNC_NAN)
+# if defined(PREDEF_STANDARD_C99) && !defined(TRIO_COMPILER_DECC)
+# define TRIO_NAN_C99_FUNCTION
+# else
+# if defined(NAN) && defined(__STDC_IEC_559__)
+# define TRIO_NAN_C99_MACRO
+# else
+# if defined(TRIO_IEEE_754)
+# define TRIO_NAN_IEEE_754
+# else
+# define TRIO_NAN_FALLBACK
+# endif
+# endif
+# endif
+#endif
+
+/*
+ * Resolve internal dependencies.
+ */
+#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
+# define TRIO_FUNC_INTERNAL_ISNAN
+# define TRIO_FUNC_INTERNAL_ISINF
+# if defined(TRIO_IEEE_754)
+# define TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY
+# define TRIO_FUNC_INTERNAL_IS_NEGATIVE
+# endif
+#endif
+
+#if defined(TRIO_NZERO_IEEE_754) \
+ || defined(TRIO_PINF_IEEE_754) \
+ || defined(TRIO_NAN_IEEE_754)
+# define TRIO_FUNC_INTERNAL_MAKE_DOUBLE
#endif
+#if defined(TRIO_FUNC_INTERNAL_ISNAN)
+# if defined(PREDEF_STANDARD_XPG3)
+# define TRIO_INTERNAL_ISNAN_XPG3
+# else
+# if defined(TRIO_IEEE_754)
+# define TRIO_INTERNAL_ISNAN_IEEE_754
+# else
+# define TRIO_INTERNAL_ISNAN_FALLBACK
+# endif
+# endif
+#endif
+
+#if defined(TRIO_FUNC_INTERNAL_ISINF)
+# if defined(TRIO_IEEE_754)
+# define TRIO_INTERNAL_ISINF_IEEE_754
+# else
+# define TRIO_INTERNAL_ISINF_FALLBACK
+# endif
+#endif
/*************************************************************************
* Constants
*/
-static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.26 2002/12/08 12:08:21 breese Exp $";
-
-#if defined(USE_IEEE_754)
+#if !defined(TRIO_EMBED_NAN)
+static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $";
+#endif
+#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \
+ || defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY) \
+ || defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
/*
* Endian-agnostic indexing macro.
*
@@ -124,9 +245,10 @@ static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.26 2002/12/08 12:08:21
* for the IEEE 754 bit-patterns and masks.
*/
#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
-
static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
+#endif
+#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
/* Mask for the exponent */
static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
@@ -136,37 +258,48 @@ static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
+#endif
+#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
/* Mask for the sign bit */
static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+#endif
+#if defined(TRIO_NZERO_IEEE_754)
/* Bit-pattern for negative zero */
static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+#endif
+#if defined(TRIO_PINF_IEEE_754)
/* Bit-pattern for infinity */
static TRIO_CONST unsigned char ieee_754_infinity_array[] = {
0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+#endif
+#if defined(TRIO_NAN_IEEE_754)
/* Bit-pattern for quiet NaN */
static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+#endif
/*************************************************************************
- * Functions
+ * Internal functions
*/
/*
- * trio_make_double
+ * internal_make_double
*/
-TRIO_PRIVATE double
-trio_make_double
+#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE)
+
+TRIO_PRIVATE_NAN double
+internal_make_double
TRIO_ARGS1((values),
TRIO_CONST unsigned char *values)
{
@@ -179,11 +312,15 @@ TRIO_ARGS1((values),
return result;
}
+#endif
+
/*
- * trio_is_special_quantity
+ * internal_is_special_quantity
*/
-TRIO_PRIVATE int
-trio_is_special_quantity
+#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
+
+TRIO_PRIVATE_NAN int
+internal_is_special_quantity
TRIO_ARGS2((number, has_mantissa),
double number,
int *has_mantissa)
@@ -203,11 +340,15 @@ TRIO_ARGS2((number, has_mantissa),
return is_special_quantity;
}
+#endif
+
/*
- * trio_is_negative
+ * internal_is_negative
*/
-TRIO_PRIVATE int
-trio_is_negative
+#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
+
+TRIO_PRIVATE_NAN int
+internal_is_negative
TRIO_ARGS1((number),
double number)
{
@@ -221,167 +362,271 @@ TRIO_ARGS1((number),
return is_negative;
}
-#endif /* USE_IEEE_754 */
-
+#endif
-/**
- Generate negative zero.
+#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
- @return Floating-point representation of negative zero.
-*/
-TRIO_PUBLIC double
-trio_nzero(TRIO_NOARGS)
+TRIO_PRIVATE_NAN TRIO_INLINE int
+c99_fpclassify_and_signbit
+TRIO_ARGS2((number, is_negative),
+ double number,
+ int *is_negative)
{
-#if defined(USE_IEEE_754)
- return trio_make_double(ieee_754_negzero_array);
-#else
- TRIO_VOLATILE double zero = 0.0;
-
- return -zero;
-#endif
+ *is_negative = signbit(number);
+ switch (fpclassify(number)) {
+ case FP_NAN:
+ return TRIO_FP_NAN;
+ case FP_INFINITE:
+ return TRIO_FP_INFINITE;
+ case FP_SUBNORMAL:
+ return TRIO_FP_SUBNORMAL;
+ case FP_ZERO:
+ return TRIO_FP_ZERO;
+ default:
+ return TRIO_FP_NORMAL;
+ }
}
-/**
- Generate positive infinity.
+#endif /* TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT */
- @return Floating-point representation of positive infinity.
-*/
-TRIO_PUBLIC double
-trio_pinf(TRIO_NOARGS)
-{
- /* Cache the result */
- static double result = 0.0;
+#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
- if (result == 0.0) {
-
-#if defined(INFINITY) && defined(__STDC_IEC_559__)
- result = (double)INFINITY;
+TRIO_PRIVATE_NAN TRIO_INLINE int
+decc_fpclassify_and_signbit
+TRIO_ARGS2((number, is_negative),
+ double number,
+ int *is_negative)
+{
+ switch (fp_class(number)) {
+ case FP_QNAN:
+ case FP_SNAN:
+ *is_negative = TRIO_FALSE; /* NaN has no sign */
+ return TRIO_FP_NAN;
+ case FP_POS_INF:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_INFINITE;
+ case FP_NEG_INF:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_INFINITE;
+ case FP_POS_DENORM:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_SUBNORMAL;
+ case FP_NEG_DENORM:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_SUBNORMAL;
+ case FP_POS_ZERO:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_ZERO;
+ case FP_NEG_ZERO:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_ZERO;
+ case FP_POS_NORM:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_NORMAL;
+ case FP_NEG_NORM:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_NORMAL;
+ default:
+ *is_negative = (number < 0.0);
+ return TRIO_FP_NORMAL;
+ }
+}
-#elif defined(USE_IEEE_754)
- result = trio_make_double(ieee_754_infinity_array);
+#endif /* TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT */
-#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
+#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
- result = HUGE_VAL;
- if (HUGE_VAL == DBL_MAX) {
- /* Force overflow */
- result += HUGE_VAL;
- }
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
+TRIO_PRIVATE_NAN int
+ms_fpclassify_and_signbit
+TRIO_ARGS2((number, is_negative),
+ double number,
+ int *is_negative)
+{
+ int result;
+# if defined(TRIO_COMPILER_BORLAND)
+ /*
+ * The floating-point precision may be changed by the Borland _fpclass()
+ * function, so we have to save and restore the floating-point control mask.
+ */
+ unsigned int mask;
+ /* Remember the old mask */
+ mask = _control87(0, 0);
# endif
-
-#endif
+
+ switch (_fpclass(number)) {
+ case _FPCLASS_QNAN:
+ case _FPCLASS_SNAN:
+ *is_negative = TRIO_FALSE; /* NaN has no sign */
+ result = TRIO_FP_NAN;
+ break;
+ case _FPCLASS_PINF:
+ *is_negative = TRIO_FALSE;
+ result = TRIO_FP_INFINITE;
+ break;
+ case _FPCLASS_NINF:
+ *is_negative = TRIO_TRUE;
+ result = TRIO_FP_INFINITE;
+ break;
+ case _FPCLASS_PD:
+ *is_negative = TRIO_FALSE;
+ result = TRIO_FP_SUBNORMAL;
+ break;
+ case _FPCLASS_ND:
+ *is_negative = TRIO_TRUE;
+ result = TRIO_FP_SUBNORMAL;
+ break;
+ case _FPCLASS_PZ:
+ *is_negative = TRIO_FALSE;
+ result = TRIO_FP_ZERO;
+ break;
+ case _FPCLASS_NZ:
+ *is_negative = TRIO_TRUE;
+ result = TRIO_FP_ZERO;
+ break;
+ case _FPCLASS_PN:
+ *is_negative = TRIO_FALSE;
+ result = TRIO_FP_NORMAL;
+ break;
+ case _FPCLASS_NN:
+ *is_negative = TRIO_TRUE;
+ result = TRIO_FP_NORMAL;
+ break;
+ default:
+ *is_negative = (number < 0.0);
+ result = TRIO_FP_NORMAL;
+ break;
}
+
+# if defined(TRIO_COMPILER_BORLAND)
+ /* Restore the old precision */
+ (void)_control87(mask, MCW_PC);
+# endif
+
return result;
}
-/**
- Generate negative infinity.
+#endif /* TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT */
- @return Floating-point value of negative infinity.
-*/
-TRIO_PUBLIC double
-trio_ninf(TRIO_NOARGS)
-{
- static double result = 0.0;
+#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
- if (result == 0.0) {
- /*
- * Negative infinity is calculated by negating positive infinity,
- * which can be done because it is legal to do calculations on
- * infinity (for example, 1 / infinity == 0).
- */
- result = -trio_pinf();
+TRIO_PRIVATE_NAN TRIO_INLINE int
+hp_fpclassify_and_signbit
+TRIO_ARGS2((number, is_negative),
+ double number,
+ int *is_negative)
+{
+ /*
+ * HP-UX 9.x and 10.x have an fpclassify() function, that is different
+ * from the C99 fpclassify() macro supported on HP-UX 11.x.
+ */
+ switch (fpclassify(number)) {
+ case FP_QNAN:
+ case FP_SNAN:
+ *is_negative = TRIO_FALSE; /* NaN has no sign */
+ return TRIO_FP_NAN;
+ case FP_PLUS_INF:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_INFINITE;
+ case FP_MINUS_INF:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_INFINITE;
+ case FP_PLUS_DENORM:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_SUBNORMAL;
+ case FP_MINUS_DENORM:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_SUBNORMAL;
+ case FP_PLUS_ZERO:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_ZERO;
+ case FP_MINUS_ZERO:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_ZERO;
+ case FP_PLUS_NORM:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_NORMAL;
+ case FP_MINUS_NORM:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_NORMAL;
+ default:
+ *is_negative = (number < 0.0);
+ return TRIO_FP_NORMAL;
}
- return result;
}
-/**
- Generate NaN.
-
- @return Floating-point representation of NaN.
-*/
-TRIO_PUBLIC double
-trio_nan(TRIO_NOARGS)
-{
- /* Cache the result */
- static double result = 0.0;
+#endif /* TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT */
- if (result == 0.0) {
-
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
- result = nan("");
-
-#elif defined(NAN) && defined(__STDC_IEC_559__)
- result = (double)NAN;
-
-#elif defined(USE_IEEE_754)
- result = trio_make_double(ieee_754_qnan_array);
+#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
-#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);
+TRIO_PRIVATE_NAN TRIO_INLINE int
+xlc_fpclassify_and_signbit
+TRIO_ARGS2((number, is_negative),
+ double number,
+ int *is_negative)
+{
+ /*
+ * AIX has class() for C, and _class() for C++
+ */
+# if defined(__cplusplus)
+# define AIX_CLASS(n) _class(n)
+# else
+# define AIX_CLASS(n) class(n)
# endif
-
-#endif
+
+ switch (AIX_CLASS(number)) {
+ case FP_QNAN:
+ case FP_SNAN:
+ *is_negative = TRIO_FALSE; /* NaN has no sign */
+ return TRIO_FP_NAN;
+ case FP_PLUS_INF:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_INFINITE;
+ case FP_MINUS_INF:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_INFINITE;
+ case FP_PLUS_DENORM:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_SUBNORMAL;
+ case FP_MINUS_DENORM:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_SUBNORMAL;
+ case FP_PLUS_ZERO:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_ZERO;
+ case FP_MINUS_ZERO:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_ZERO;
+ case FP_PLUS_NORM:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_NORMAL;
+ case FP_MINUS_NORM:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_NORMAL;
+ default:
+ *is_negative = (number < 0.0);
+ return TRIO_FP_NORMAL;
}
- return result;
}
-/**
- Check for NaN.
+#endif /* TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT */
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number is a NaN.
-*/
-TRIO_PUBLIC int
-trio_isnan
+#if defined(TRIO_FUNC_INTERNAL_ISNAN)
+
+TRIO_PRIVATE_NAN TRIO_INLINE int
+internal_isnan
TRIO_ARGS1((number),
double number)
{
-#if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \
- || defined(TRIO_COMPILER_SUPPORTS_UNIX95)
+# if defined(TRIO_INTERNAL_ISNAN_XPG3) || defined(TRIO_PLATFORM_SYMBIAN)
/*
- * C99 defines isnan() as a macro. UNIX95 defines isnan() as a
- * function. This function was already present in XPG4, but this
- * is a bit tricky to detect with compiler defines, so we choose
- * the conservative approach and only use it for UNIX95.
+ * XPG3 defines isnan() as a function.
*/
return isnan(number);
-
-#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
- /*
- * Microsoft Visual C++ and Borland C++ Builder have an _isnan()
- * function.
- */
- return _isnan(number) ? TRIO_TRUE : TRIO_FALSE;
-#elif defined(USE_IEEE_754)
+# endif
+
+# if defined(TRIO_INTERNAL_ISNAN_IEEE_754)
+
/*
* Examine IEEE 754 bit-pattern. A NaN must have a special exponent
* pattern, and a non-empty mantissa.
@@ -389,20 +634,23 @@ TRIO_ARGS1((number),
int has_mantissa;
int is_special_quantity;
- is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
+ is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
return (is_special_quantity && has_mantissa);
-#else
+# endif
+
+# if defined(TRIO_INTERNAL_ISNAN_FALLBACK)
+
/*
* Fallback solution
*/
int status;
double integral, fraction;
-# if defined(TRIO_PLATFORM_UNIX)
+# if defined(TRIO_PLATFORM_UNIX)
void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
+# endif
status = (/*
* NaN is the only number which does not compare to itself
@@ -415,53 +663,31 @@ TRIO_ARGS1((number),
(fraction = modf(number, &integral),
integral == fraction)));
-# if defined(TRIO_PLATFORM_UNIX)
+# if defined(TRIO_PLATFORM_UNIX)
signal(SIGFPE, signal_handler);
-# endif
+# endif
return status;
-#endif
+# endif
}
-/**
- Check for infinity.
+#endif /* TRIO_FUNC_INTERNAL_ISNAN */
- @param number An arbitrary floating-point number.
- @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
-*/
-TRIO_PUBLIC int
-trio_isinf
+#if defined(TRIO_FUNC_INTERNAL_ISINF)
+
+TRIO_PRIVATE_NAN TRIO_INLINE int
+internal_isinf
TRIO_ARGS1((number),
double number)
{
-#if defined(TRIO_COMPILER_DECC)
- /*
- * DECC has an isinf() macro, but it works differently than that
- * of C99, so we use the fp_class() function instead.
- */
- return ((fp_class(number) == FP_POS_INF)
- ? 1
- : ((fp_class(number) == FP_NEG_INF) ? -1 : 0));
+# if defined(TRIO_PLATFORM_SYMBIAN)
-#elif defined(isinf)
- /*
- * C99 defines isinf() as a macro.
- */
- return isinf(number)
- ? ((number > 0.0) ? 1 : -1)
- : 0;
-
-#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
- /*
- * Microsoft Visual C++ and Borland C++ Builder have an _fpclass()
- * function that can be used to detect infinity.
- */
- return ((_fpclass(number) == _FPCLASS_PINF)
- ? 1
- : ((_fpclass(number) == _FPCLASS_NINF) ? -1 : 0));
+ return isinf(number);
-#elif defined(USE_IEEE_754)
+# endif
+
+# if defined(TRIO_INTERNAL_ISINF_IEEE_754)
/*
* Examine IEEE 754 bit-pattern. Infinity must have a special exponent
* pattern, and an empty mantissa.
@@ -469,21 +695,24 @@ TRIO_ARGS1((number),
int has_mantissa;
int is_special_quantity;
- is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
+ is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
return (is_special_quantity && !has_mantissa)
? ((number < 0.0) ? -1 : 1)
: 0;
-#else
+# endif
+
+# if defined(TRIO_INTERNAL_ISINF_FALLBACK)
+
/*
* Fallback solution.
*/
int status;
-# if defined(TRIO_PLATFORM_UNIX)
+# if defined(TRIO_PLATFORM_UNIX)
void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
+# endif
double infinity = trio_pinf();
@@ -491,185 +720,63 @@ TRIO_ARGS1((number),
? 1
: ((number == -infinity) ? -1 : 0));
-# if defined(TRIO_PLATFORM_UNIX)
+# if defined(TRIO_PLATFORM_UNIX)
signal(SIGFPE, signal_handler);
-# endif
+# endif
return status;
-
-#endif
+
+# endif
}
+#endif /* TRIO_FUNC_INTERNAL_ISINF */
-/**
- Check for finity.
+/*************************************************************************
+ * Public functions
+ */
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number is a finite.
-*/
-TRIO_PUBLIC int
-trio_isfinite
-TRIO_ARGS1((number),
- double number)
+#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
+
+TRIO_PUBLIC_NAN int
+trio_fpclassify_and_signbit
+TRIO_ARGS2((number, is_negative),
+ double number,
+ int *is_negative)
{
-#if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite)
- /*
- * C99 defines isfinite() as a macro.
- */
- return isfinite(number);
+ /* The TRIO_FUNC_xxx_FPCLASSIFY_AND_SIGNBIT macros are mutually exclusive */
-#elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
- /*
- * Microsoft Visual C++ and Borland C++ Builder use _finite().
- */
- return _finite(number);
+#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
-#elif defined(USE_IEEE_754)
- /*
- * Examine IEEE 754 bit-pattern. For finity we do not care about the
- * mantissa.
- */
- int dummy;
+ return c99_fpclassify_and_signbit(number, is_negative);
- return (! trio_is_special_quantity(number, &dummy));
+#endif
+
+#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
+
+ return decc_fpclassify_and_signbit(number, is_negative);
-#else
- /*
- * Fallback solution.
- */
- return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0));
-
#endif
-}
+#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
-/*
- * The sign of NaN is always false
- */
-TRIO_PUBLIC int
-trio_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
- double number,
- int *is_negative)
-{
-#if defined(fpclassify) && defined(signbit)
- /*
- * C99 defines fpclassify() and signbit() as a macros
- */
- *is_negative = signbit(number);
- switch (fpclassify(number)) {
- case FP_NAN:
- return TRIO_FP_NAN;
- case FP_INFINITE:
- return TRIO_FP_INFINITE;
- case FP_SUBNORMAL:
- return TRIO_FP_SUBNORMAL;
- case FP_ZERO:
- return TRIO_FP_ZERO;
- default:
- return TRIO_FP_NORMAL;
- }
+ return ms_fpclassify_and_signbit(number, is_negative);
-#else
-# if defined(TRIO_COMPILER_DECC)
- /*
- * DECC has an fp_class() function.
- */
-# define TRIO_FPCLASSIFY(n) fp_class(n)
-# define TRIO_QUIET_NAN FP_QNAN
-# define TRIO_SIGNALLING_NAN FP_SNAN
-# define TRIO_POSITIVE_INFINITY FP_POS_INF
-# define TRIO_NEGATIVE_INFINITY FP_NEG_INF
-# define TRIO_POSITIVE_SUBNORMAL FP_POS_DENORM
-# define TRIO_NEGATIVE_SUBNORMAL FP_NEG_DENORM
-# define TRIO_POSITIVE_ZERO FP_POS_ZERO
-# define TRIO_NEGATIVE_ZERO FP_NEG_ZERO
-# define TRIO_POSITIVE_NORMAL FP_POS_NORM
-# define TRIO_NEGATIVE_NORMAL FP_NEG_NORM
-
-# elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
- /*
- * Microsoft Visual C++ and Borland C++ Builder have an _fpclass()
- * function.
- */
-# define TRIO_FPCLASSIFY(n) _fpclass(n)
-# define TRIO_QUIET_NAN _FPCLASS_QNAN
-# define TRIO_SIGNALLING_NAN _FPCLASS_SNAN
-# define TRIO_POSITIVE_INFINITY _FPCLASS_PINF
-# define TRIO_NEGATIVE_INFINITY _FPCLASS_NINF
-# define TRIO_POSITIVE_SUBNORMAL _FPCLASS_PD
-# define TRIO_NEGATIVE_SUBNORMAL _FPCLASS_ND
-# define TRIO_POSITIVE_ZERO _FPCLASS_PZ
-# define TRIO_NEGATIVE_ZERO _FPCLASS_NZ
-# define TRIO_POSITIVE_NORMAL _FPCLASS_PN
-# define TRIO_NEGATIVE_NORMAL _FPCLASS_NN
-
-# elif defined(FP_PLUS_NORM)
- /*
- * HP-UX 9.x and 10.x have an fpclassify() function, that is different
- * from the C99 fpclassify() macro supported on HP-UX 11.x.
- *
- * AIX has class() for C, and _class() for C++, which returns the
- * same values as the HP-UX fpclassify() function.
- */
-# if defined(TRIO_PLATFORM_AIX)
-# if defined(__cplusplus)
-# define TRIO_FPCLASSIFY(n) _class(n)
-# else
-# define TRIO_FPCLASSIFY(n) class(n)
-# endif
-# else
-# define TRIO_FPCLASSIFY(n) fpclassify(n)
-# endif
-# define TRIO_QUIET_NAN FP_QNAN
-# define TRIO_SIGNALLING_NAN FP_SNAN
-# define TRIO_POSITIVE_INFINITY FP_PLUS_INF
-# define TRIO_NEGATIVE_INFINITY FP_MINUS_INF
-# define TRIO_POSITIVE_SUBNORMAL FP_PLUS_DENORM
-# define TRIO_NEGATIVE_SUBNORMAL FP_MINUS_DENORM
-# define TRIO_POSITIVE_ZERO FP_PLUS_ZERO
-# define TRIO_NEGATIVE_ZERO FP_MINUS_ZERO
-# define TRIO_POSITIVE_NORMAL FP_PLUS_NORM
-# define TRIO_NEGATIVE_NORMAL FP_MINUS_NORM
-# endif
+#endif
-# if defined(TRIO_FPCLASSIFY)
- switch (TRIO_FPCLASSIFY(number)) {
- case TRIO_QUIET_NAN:
- case TRIO_SIGNALLING_NAN:
- *is_negative = TRIO_FALSE; /* NaN has no sign */
- return TRIO_FP_NAN;
- case TRIO_POSITIVE_INFINITY:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_INFINITE;
- case TRIO_NEGATIVE_INFINITY:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_INFINITE;
- case TRIO_POSITIVE_SUBNORMAL:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- case TRIO_NEGATIVE_SUBNORMAL:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- case TRIO_POSITIVE_ZERO:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_ZERO;
- case TRIO_NEGATIVE_ZERO:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_ZERO;
- case TRIO_POSITIVE_NORMAL:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NORMAL;
- case TRIO_NEGATIVE_NORMAL:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_NORMAL;
- default:
- /* Just in case... */
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
- }
+#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
+
+ return hp_fpclassify_and_signbit(number, is_negative);
+
+#endif
+
+#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
+
+ return xlc_fpclassify_and_signbit(number, is_negative);
+
+#endif
+
+#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
-# else
/*
* Fallback solution.
*/
@@ -681,18 +788,19 @@ TRIO_ARGS2((number, is_negative),
* have to handle this as a special case by examining the sign bit
* directly.
*/
-# if defined(USE_IEEE_754)
- *is_negative = trio_is_negative(number);
-# else
+# if defined(TRIO_IEEE_754)
+ *is_negative = internal_is_negative(number);
+# else
*is_negative = TRIO_FALSE; /* FIXME */
-# endif
+# endif
return TRIO_FP_ZERO;
}
- if (trio_isnan(number)) {
+ if (internal_isnan(number)) {
*is_negative = TRIO_FALSE;
return TRIO_FP_NAN;
}
- if ((rc = trio_isinf(number))) {
+ rc = internal_isinf(number);
+ if (rc != 0) {
*is_negative = (rc == -1);
return TRIO_FP_INFINITE;
}
@@ -706,11 +814,86 @@ TRIO_ARGS2((number, is_negative),
}
*is_negative = (number < 0.0);
return TRIO_FP_NORMAL;
+
+#endif
+}
+
+#endif
+
+/**
+ Check for NaN.
+
+ @param number An arbitrary floating-point number.
+ @return Boolean value indicating whether or not the number is a NaN.
+*/
+#if defined(TRIO_FUNC_ISNAN)
+
+TRIO_PUBLIC_NAN int
+trio_isnan
+TRIO_ARGS1((number),
+ double number)
+{
+ int dummy;
-# endif
+ return (trio_fpclassify_and_signbit(number, &dummy) == TRIO_FP_NAN);
+}
+
+#endif
+
+/**
+ Check for infinity.
+
+ @param number An arbitrary floating-point number.
+ @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
+*/
+#if defined(TRIO_FUNC_ISINF)
+
+TRIO_PUBLIC_NAN int
+trio_isinf
+TRIO_ARGS1((number),
+ double number)
+{
+ int is_negative;
+
+ if (trio_fpclassify_and_signbit(number, &is_negative) == TRIO_FP_INFINITE)
+ {
+ return (is_negative) ? -1 : 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
#endif
+
+/**
+ Check for finity.
+
+ @param number An arbitrary floating-point number.
+ @return Boolean value indicating whether or not the number is a finite.
+*/
+#if defined(TRIO_FUNC_ISFINITE)
+
+TRIO_PUBLIC_NAN int
+trio_isfinite
+TRIO_ARGS1((number),
+ double number)
+{
+ int dummy;
+
+ switch (trio_fpclassify_and_signbit(number, &dummy))
+ {
+ case TRIO_FP_INFINITE:
+ case TRIO_FP_NAN:
+ return 0;
+ default:
+ return 1;
+ }
}
+#endif
+
/**
Examine the sign of a number.
@@ -718,7 +901,9 @@ TRIO_ARGS2((number, is_negative),
@return Boolean value indicating whether or not the number has the
sign bit set (i.e. is negative).
*/
-TRIO_PUBLIC int
+#if defined(TRIO_FUNC_SIGNBIT)
+
+TRIO_PUBLIC_NAN int
trio_signbit
TRIO_ARGS1((number),
double number)
@@ -729,13 +914,17 @@ TRIO_ARGS1((number),
return is_negative;
}
+#endif
+
/**
Examine the class of a number.
@param number An arbitrary floating-point number.
@return Enumerable value indicating the class of @p number
*/
-TRIO_PUBLIC int
+#if defined(TRIO_FUNC_FPCLASSIFY)
+
+TRIO_PUBLIC_NAN int
trio_fpclassify
TRIO_ARGS1((number),
double number)
@@ -745,6 +934,173 @@ TRIO_ARGS1((number),
return trio_fpclassify_and_signbit(number, &dummy);
}
+#endif
+
+/**
+ Generate negative zero.
+
+ @return Floating-point representation of negative zero.
+*/
+#if defined(TRIO_FUNC_NZERO)
+
+TRIO_PUBLIC_NAN double
+trio_nzero(TRIO_NOARGS)
+{
+# if defined(TRIO_NZERO_IEEE_754)
+
+ return internal_make_double(ieee_754_negzero_array);
+
+# endif
+
+# if defined(TRIO_NZERO_FALLBACK)
+
+ TRIO_VOLATILE double zero = 0.0;
+
+ return -zero;
+
+# endif
+}
+
+#endif
+
+/**
+ Generate positive infinity.
+
+ @return Floating-point representation of positive infinity.
+*/
+#if defined(TRIO_FUNC_PINF)
+
+TRIO_PUBLIC_NAN double
+trio_pinf(TRIO_NOARGS)
+{
+ /* Cache the result */
+ static double pinf_value = 0.0;
+
+ if (pinf_value == 0.0) {
+
+# if defined(TRIO_PINF_C99_MACRO)
+
+ pinf_value = (double)INFINITY;
+
+# endif
+
+# if defined(TRIO_PINF_IEEE_754)
+
+ pinf_value = internal_make_double(ieee_754_infinity_array);
+
+# endif
+
+# if defined(TRIO_PINF_FALLBACK)
+ /*
+ * 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
+
+ pinf_value = HUGE_VAL;
+ if (HUGE_VAL == DBL_MAX) {
+ /* Force overflow */
+ pinf_value += HUGE_VAL;
+ }
+
+# if defined(TRIO_PLATFORM_UNIX)
+ signal(SIGFPE, signal_handler);
+# endif
+
+# endif
+ }
+ return pinf_value;
+}
+
+#endif
+
+/**
+ Generate negative infinity.
+
+ @return Floating-point value of negative infinity.
+*/
+#if defined(TRIO_FUNC_NINF)
+
+TRIO_PUBLIC_NAN double
+trio_ninf(TRIO_NOARGS)
+{
+ static double ninf_value = 0.0;
+
+ if (ninf_value == 0.0) {
+ /*
+ * Negative infinity is calculated by negating positive infinity,
+ * which can be done because it is legal to do calculations on
+ * infinity (for example, 1 / infinity == 0).
+ */
+ ninf_value = -trio_pinf();
+ }
+ return ninf_value;
+}
+
+#endif
+
+/**
+ Generate NaN.
+
+ @return Floating-point representation of NaN.
+*/
+#if defined(TRIO_FUNC_NAN)
+
+TRIO_PUBLIC_NAN double
+trio_nan(TRIO_NOARGS)
+{
+ /* Cache the result */
+ static double nan_value = 0.0;
+
+ if (nan_value == 0.0) {
+
+# if defined(TRIO_NAN_C99_FUNCTION) || defined(TRIO_PLATFORM_SYMBIAN)
+
+ nan_value = nan("");
+
+# endif
+
+# if defined(TRIO_NAN_C99_MACRO)
+
+ nan_value = (double)NAN;
+
+# endif
+
+# if defined(TRIO_NAN_IEEE_754)
+
+ nan_value = internal_make_double(ieee_754_qnan_array);
+
+# endif
+
+# if defined(TRIO_NAN_FALLBACK)
+ /*
+ * 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
+
+ nan_value = trio_pinf() / trio_pinf();
+
+# if defined(TRIO_PLATFORM_UNIX)
+ signal(SIGFPE, signal_handler);
+# endif
+
+# endif
+ }
+ return nan_value;
+}
+
+#endif
/** @} SpecialQuantities */
@@ -816,7 +1172,7 @@ int main(TRIO_NOARGS)
print_class("PSub", 1.01e-307 - 1.00e-307);
print_class("NSub", 1.00e-307 - 1.01e-307);
- printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+ printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
my_nan,
((unsigned char *)&my_nan)[0],
((unsigned char *)&my_nan)[1],
@@ -826,8 +1182,8 @@ int main(TRIO_NOARGS)
((unsigned char *)&my_nan)[5],
((unsigned char *)&my_nan)[6],
((unsigned char *)&my_nan)[7],
- trio_isnan(my_nan), trio_isinf(my_nan));
- printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+ trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
+ printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
my_pinf,
((unsigned char *)&my_pinf)[0],
((unsigned char *)&my_pinf)[1],
@@ -837,8 +1193,8 @@ int main(TRIO_NOARGS)
((unsigned char *)&my_pinf)[5],
((unsigned char *)&my_pinf)[6],
((unsigned char *)&my_pinf)[7],
- trio_isnan(my_pinf), trio_isinf(my_pinf));
- printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+ trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
+ printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
my_ninf,
((unsigned char *)&my_ninf)[0],
((unsigned char *)&my_ninf)[1],
@@ -848,7 +1204,7 @@ int main(TRIO_NOARGS)
((unsigned char *)&my_ninf)[5],
((unsigned char *)&my_ninf)[6],
((unsigned char *)&my_ninf)[7],
- trio_isnan(my_ninf), trio_isinf(my_ninf));
+ trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
# if defined(TRIO_PLATFORM_UNIX)
signal_handler = signal(SIGFPE, SIG_IGN);
@@ -862,7 +1218,7 @@ int main(TRIO_NOARGS)
signal(SIGFPE, signal_handler);
# endif
- printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+ printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
my_nan,
((unsigned char *)&my_nan)[0],
((unsigned char *)&my_nan)[1],
@@ -872,8 +1228,8 @@ int main(TRIO_NOARGS)
((unsigned char *)&my_nan)[5],
((unsigned char *)&my_nan)[6],
((unsigned char *)&my_nan)[7],
- trio_isnan(my_nan), trio_isinf(my_nan));
- printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+ trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
+ printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
my_pinf,
((unsigned char *)&my_pinf)[0],
((unsigned char *)&my_pinf)[1],
@@ -883,8 +1239,8 @@ int main(TRIO_NOARGS)
((unsigned char *)&my_pinf)[5],
((unsigned char *)&my_pinf)[6],
((unsigned char *)&my_pinf)[7],
- trio_isnan(my_pinf), trio_isinf(my_pinf));
- printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
+ trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
+ printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
my_ninf,
((unsigned char *)&my_ninf)[0],
((unsigned char *)&my_ninf)[1],
@@ -894,7 +1250,7 @@ int main(TRIO_NOARGS)
((unsigned char *)&my_ninf)[5],
((unsigned char *)&my_ninf)[6],
((unsigned char *)&my_ninf)[7],
- trio_isnan(my_ninf), trio_isinf(my_ninf));
+ trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
return 0;
}