aboutsummaryrefslogtreecommitdiffstats
path: root/trionan.c
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2002-09-25 22:44:43 +0000
committerDaniel Veillard <veillard@src.gnome.org>2002-09-25 22:44:43 +0000
commitb7c29c38f507ac62cc85df9b897762fc84f05a68 (patch)
tree239e110c068139b88c1c78ed6bfede06cd66fbca /trionan.c
parentbd9afb529069415baf1f32d907f035de19dae788 (diff)
downloadandroid_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.c185
1 files changed, 120 insertions, 65 deletions
diff --git a/trionan.c b/trionan.c
index 6f67c5be..5d63ad78 100644
--- a/trionan.c
+++ b/trionan.c
@@ -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();