diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2002-09-25 22:44:43 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2002-09-25 22:44:43 +0000 |
commit | b7c29c38f507ac62cc85df9b897762fc84f05a68 (patch) | |
tree | 239e110c068139b88c1c78ed6bfede06cd66fbca /trionan.c | |
parent | bd9afb529069415baf1f32d907f035de19dae788 (diff) | |
download | android_external_libxml2-b7c29c38f507ac62cc85df9b897762fc84f05a68.tar.gz android_external_libxml2-b7c29c38f507ac62cc85df9b897762fc84f05a68.tar.bz2 android_external_libxml2-b7c29c38f507ac62cc85df9b897762fc84f05a68.zip |
applied a trio update patch from Bjorn Reese which should work with MinGW
* trio.c trio.h triodef.h trionan.c trionan.h triop.h
triostr.c triostr.h: applied a trio update patch from
Bjorn Reese which should work with MinGW
Daniel
Diffstat (limited to 'trionan.c')
-rw-r--r-- | trionan.c | 185 |
1 files changed, 120 insertions, 65 deletions
@@ -29,40 +29,13 @@ * 2. Use IEEE 754 bit-patterns if possible. * 3. Use platform-specific techniques. * - * This program has been tested on the following platforms (in - * alphabetic order) - * - * OS CPU Compiler - * ------------------------------------------------- - * AIX 4.1.4 PowerPC gcc - * Darwin 1.3.7 PowerPC gcc - * FreeBSD 2.2 x86 gcc - * FreeBSD 3.3 x86 gcc - * FreeBSD 4.3 x86 gcc - * FreeBSD 4.3 Alpha gcc - * HP-UX 10.20 PA-RISC gcc - * HP-UX 10.20 PA-RISC HP C++ - * IRIX 6.5 MIPS MIPSpro C - * Linux 2.2 x86 gcc - * Linux 2.2 Alpha gcc - * Linux 2.4 IA64 gcc - * Linux 2.4 StrongARM gcc - * NetBSD 1.4 x86 gcc - * NetBSD 1.4 StrongARM gcc - * NetBSD 1.5 Alpha gcc - * OpenVMS 7.1 Alpha DEC C 6.0 - * RISC OS 4 StrongARM Norcroft C - * Solaris 2.5.1 x86 gcc - * Solaris 2.5.1 Sparc gcc - * Solaris 2.6 Sparc WorkShop 4.2 - * Solaris 8 Sparc Forte C 6 - * Tru64 4.0D Alpha gcc - * Tru64 5.1 Alpha gcc - * WinNT x86 MSVC 5.0 & 6.0 - * ************************************************************************/ -static const char rcsid[] = "@(#)$Id$"; +/* + * TODO: + * o Put all the magic into trio_fpclassify_and_signbit(), and use this from + * trio_isnan() etc. + */ /************************************************************************* * Include files @@ -102,7 +75,9 @@ static const char rcsid[] = "@(#)$Id$"; # if defined(TRIO_PLATFORM_VMS) # error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE" # else -# error "Must be compiled with option -ieee" +# if !defined(_CFE) +# 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" @@ -128,9 +103,11 @@ static const char rcsid[] = "@(#)$Id$"; /************************************************************************* - * Data + * Constants */ +static TRIO_CONST char rcsid[] = "@(#)$Id$"; + #if defined(USE_IEEE_754) /* @@ -187,7 +164,9 @@ static TRIO_CONST unsigned char ieee_754_qnan_array[] = { * trio_make_double */ TRIO_PRIVATE double -trio_make_double(TRIO_CONST unsigned char *values) +trio_make_double +TRIO_ARGS1((values), + TRIO_CONST unsigned char *values) { TRIO_VOLATILE double result; int i; @@ -202,8 +181,10 @@ trio_make_double(TRIO_CONST unsigned char *values) * trio_is_special_quantity */ TRIO_PRIVATE int -trio_is_special_quantity(double number, - int *has_mantissa) +trio_is_special_quantity +TRIO_ARGS2((number, has_mantissa), + double number, + int *has_mantissa) { unsigned int i; unsigned char current; @@ -224,7 +205,9 @@ trio_is_special_quantity(double number, * trio_is_negative */ TRIO_PRIVATE int -trio_is_negative(double number) +trio_is_negative +TRIO_ARGS1((number), + double number) { unsigned int i; int is_negative = TRIO_FALSE; @@ -236,14 +219,25 @@ trio_is_negative(double number) return is_negative; } +#endif /* USE_IEEE_754 */ + + +/** + Generate negative zero. + + @return Floating-point representation of negative zero. +*/ TRIO_PUBLIC double -trio_nzero(void) +trio_nzero(TRIO_NOARGS) { +#if defined(USE_IEEE_754) return trio_make_double(ieee_754_negzero_array); -} - -#endif /* USE_IEEE_754 */ +#else + TRIO_VOLATILE double zero = 0.0; + return -zero; +#endif +} /** Generate positive infinity. @@ -251,7 +245,7 @@ trio_nzero(void) @return Floating-point representation of positive infinity. */ TRIO_PUBLIC double -trio_pinf(void) +trio_pinf(TRIO_NOARGS) { /* Cache the result */ static double result = 0.0; @@ -295,7 +289,7 @@ trio_pinf(void) @return Floating-point value of negative infinity. */ TRIO_PUBLIC double -trio_ninf(void) +trio_ninf(TRIO_NOARGS) { static double result = 0.0; @@ -316,7 +310,7 @@ trio_ninf(void) @return Floating-point representation of NaN. */ TRIO_PUBLIC double -trio_nan(void) +trio_nan(TRIO_NOARGS) { /* Cache the result */ static double result = 0.0; @@ -364,9 +358,12 @@ trio_nan(void) @return Boolean value indicating whether or not the number is a NaN. */ TRIO_PUBLIC int -trio_isnan(TRIO_VOLATILE double number) +trio_isnan +TRIO_ARGS1((number), + double number) { -#if defined(isnan) || defined(TRIO_COMPILER_SUPPORTS_UNIX95) +#if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \ + || defined(TRIO_COMPILER_SUPPORTS_UNIX95) /* * C99 defines isnan() as a macro. UNIX95 defines isnan() as a * function. This function was already present in XPG4, but this @@ -407,7 +404,7 @@ trio_isnan(TRIO_VOLATILE double number) status = (/* * NaN is the only number which does not compare to itself */ - (number != number) || + ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) || /* * Fallback solution if NaN compares to NaN */ @@ -431,7 +428,9 @@ trio_isnan(TRIO_VOLATILE double number) @return 1 if positive infinity, -1 if negative infinity, 0 otherwise. */ TRIO_PUBLIC int -trio_isinf(TRIO_VOLATILE double number) +trio_isinf +TRIO_ARGS1((number), + double number) { #if defined(TRIO_COMPILER_DECC) /* @@ -441,12 +440,14 @@ trio_isinf(TRIO_VOLATILE double number) return ((fp_class(number) == FP_POS_INF) ? 1 : ((fp_class(number) == FP_NEG_INF) ? -1 : 0)); - + #elif defined(isinf) /* * C99 defines isinf() as a macro. */ - return isinf(number); + return isinf(number) + ? ((number > 0.0) ? 1 : -1) + : 0; #elif defined(TRIO_COMPILER_MSVC) /* @@ -503,9 +504,11 @@ trio_isinf(TRIO_VOLATILE double number) @return Boolean value indicating whether or not the number is a finite. */ TRIO_PUBLIC int -trio_isfinite(TRIO_VOLATILE double number) +trio_isfinite +TRIO_ARGS1((number), + double number) { -#if defined(isfinite) +#if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite) /* * C99 defines isfinite() as a macro. */ @@ -538,9 +541,11 @@ trio_isfinite(TRIO_VOLATILE double number) /* * The sign of NaN is always false */ -TRIO_PRIVATE int -trio_fpclass(TRIO_VOLATILE double number, - int *is_negative) +TRIO_PUBLIC int +trio_fpclassify_and_signbit +TRIO_ARGS2((number, is_negative), + double number, + int *is_negative) { #if defined(fpclassify) && defined(signbit) /* @@ -637,7 +642,46 @@ trio_fpclass(TRIO_VOLATILE double number, *is_negative = (number < 0.0); return TRIO_FP_NORMAL; } - + +#elif defined(FP_PLUS_NORM) || defined(__hpux) + + /* + * 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; + 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: + assert(0); + } + #else /* * Fallback solution. @@ -687,11 +731,13 @@ trio_fpclass(TRIO_VOLATILE double number, sign bit set (i.e. is negative). */ TRIO_PUBLIC int -trio_signbit(TRIO_VOLATILE double number) +trio_signbit +TRIO_ARGS1((number), + double number) { int is_negative; - (void)trio_fpclass(number, &is_negative); + (void)trio_fpclassify_and_signbit(number, &is_negative); return is_negative; } @@ -702,11 +748,13 @@ trio_signbit(TRIO_VOLATILE double number) @return Enumerable value indicating the class of @p number */ TRIO_PUBLIC int -trio_fpclassify(TRIO_VOLATILE double number) +trio_fpclassify +TRIO_ARGS1((number), + double number) { int dummy; - return trio_fpclass(number, &dummy); + return trio_fpclassify_and_signbit(number, &dummy); } @@ -723,7 +771,10 @@ trio_fpclassify(TRIO_VOLATILE double number) #if defined(STANDALONE) # include <stdio.h> -static const char *getClassification(int type) +static TRIO_CONST char * +getClassification +TRIO_ARGS1((type) + int type) { switch (type) { case TRIO_FP_INFINITE: @@ -741,7 +792,11 @@ static const char *getClassification(int type) } } -static void print_class(const char *prefix, double number) +static void +print_class +TRIO_ARGS2((prefix, number) + TRIO_CONST char *prefix, + double number) { printf("%-6s: %s %-15s %g\n", prefix, @@ -750,13 +805,13 @@ static void print_class(const char *prefix, double number) number); } -int main(void) +int main(TRIO_NOARGS) { double my_nan; double my_pinf; double my_ninf; # if defined(TRIO_PLATFORM_UNIX) - void (*signal_handler)(int); + void (*signal_handler) TRIO_PROTO((int)); # endif my_nan = trio_nan(); |