summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-09-01 15:00:54 +0000
committerEric Andersen <andersen@codepoet.org>2003-09-01 15:00:54 +0000
commit557ea04ce0e505c98d4b6852b194d7ed06fe8289 (patch)
tree0fc0a3a14016dd917d5174e1a355f6ba76a2f508
parente4668543352aa58a0aaa03fe9624daa75fd6da34 (diff)
Atsushi Nemoto writes:
I found math fpclassify function is broken because FP_XXX definitions in libm/fp_private.h is incompatible with include/math.h. Also I noticed fp_private.h and fpmacros.c use many 'long int' for 32bit variables. I think these should be int or u_int32_t. Here is a patch against 0.9.20. fp_private.c: --- fix union members (use u_int32_t instead of 'unsigned long int'). --- remove incompatible FP_XXX definitions (and some unused macros). fpmacros.c: --- use FP_NAN instead of FP_QNAN/FP_SNAN. --- use correct type (int instead of long int). --- fix union members (use u_int32_t instead of 'unsigned long int'). --- remove unnecessary cast. Note that I had to remove weak_alias for isnanl,isinfl to compile patched fpmacroc.c. Is this really needed? Original behavior (using isnan for isnanl) seems problematic anyway.
-rw-r--r--libm/fp_private.h33
-rw-r--r--libm/fpmacros.c101
2 files changed, 52 insertions, 82 deletions
diff --git a/libm/fp_private.h b/libm/fp_private.h
index 30b3e0572..97b3b5703 100644
--- a/libm/fp_private.h
+++ b/libm/fp_private.h
@@ -72,11 +72,11 @@
typedef struct /* Hex representation of a double. */
{
#if defined(__BIG_ENDIAN__)
- unsigned long int high;
- unsigned long int low;
+ u_int32_t high;
+ u_int32_t low;
#else
- unsigned long int low;
- unsigned long int high;
+ u_int32_t low;
+ u_int32_t high;
#endif
} dHexParts;
@@ -85,28 +85,3 @@ typedef union
unsigned char byties[8];
double dbl;
} DblInHex;
-
-//enum boolean { FALSE, TRUE };
-
-/*******************************************************************************
-* Macros to access long subfields of a double value. *
-*******************************************************************************/
-
-#define highpartd(x) *((long *) &x)
-#define lowpartd(x) *((long *) &x + 1)
-
-enum {
- FP_SNAN = 0, /* signaling NaN
- */
- FP_QNAN = 1, /* quiet NaN
- */
- FP_INFINITE = 2, /* + or - infinity
- */
- FP_ZERO = 3, /* + or - zero
- */
- FP_NORMAL = 4, /* all normal numbers
- */
- FP_SUBNORMAL = 5 /* denormal numbers
- */
-};
-
diff --git a/libm/fpmacros.c b/libm/fpmacros.c
index 10aa5bd41..968259520 100644
--- a/libm/fpmacros.c
+++ b/libm/fpmacros.c
@@ -21,6 +21,8 @@
***********************************************************************/
#include <features.h>
+#include <sys/types.h>
+#include <math.h>
#include "fp_private.h"
#define SIGN_MASK 0x80000000
@@ -29,7 +31,7 @@
#define FFRAC_MASK 0x007fffff
/***********************************************************************
- long int __fpclassifyf(float x) returns the classification code of the
+ int __fpclassifyf(float x) returns the classification code of the
argument x, as defined in <fp.h>.
Exceptions: INVALID signaled if x is a signaling NaN; in this case,
@@ -38,12 +40,12 @@
Calls: none
***********************************************************************/
-long int __fpclassifyf ( float x )
+int __fpclassifyf ( float x )
{
- unsigned long int iexp;
+ unsigned int iexp;
union {
- unsigned long int lval;
+ u_int32_t lval;
float fval;
} z;
@@ -52,20 +54,17 @@ long int __fpclassifyf ( float x )
if (iexp == FEXP_MASK) { /* NaN or INF case */
if ((z.lval & 0x007fffff) == 0)
- return (long int) FP_INFINITE;
- else if ((z.lval & 0x00400000) != 0)
- return (long int) FP_QNAN;
- else
- return (long int) FP_SNAN;
+ return FP_INFINITE;
+ return FP_NAN;
}
if (iexp != 0) /* normal float */
- return (long int) FP_NORMAL;
+ return FP_NORMAL;
if (x == 0.0)
- return (long int) FP_ZERO; /* zero */
+ return FP_ZERO; /* zero */
else
- return (long int) FP_SUBNORMAL; /* must be subnormal */
+ return FP_SUBNORMAL; /* must be subnormal */
}
@@ -79,9 +78,9 @@ long int __fpclassifyf ( float x )
Calls: none
***********************************************************************/
-long int __fpclassify ( double arg )
+int __fpclassify ( double arg )
{
- register unsigned long int exponent;
+ register unsigned int exponent;
union
{
dHexParts hex;
@@ -94,23 +93,23 @@ long int __fpclassify ( double arg )
if ( exponent == dExpMask )
{
if ( ( ( x.hex.high & dHighMan ) | x.hex.low ) == 0 )
- return (long int) FP_INFINITE;
+ return FP_INFINITE;
else
- return ( x.hex.high & 0x00080000 ) ? FP_QNAN : FP_SNAN;
+ return FP_NAN;
}
else if ( exponent != 0)
- return (long int) FP_NORMAL;
+ return FP_NORMAL;
else {
if ( arg == 0.0 )
- return (long int) FP_ZERO;
+ return FP_ZERO;
else
- return (long int) FP_SUBNORMAL;
+ return FP_SUBNORMAL;
}
}
/***********************************************************************
- long int __isnormalf(float x) returns nonzero if and only if x is a
+ int __isnormalf(float x) returns nonzero if and only if x is a
normalized float number and zero otherwise.
Exceptions: INVALID is raised if x is a signaling NaN; in this case,
@@ -119,11 +118,11 @@ long int __fpclassify ( double arg )
Calls: none
***********************************************************************/
-long int __isnormalf ( float x )
+int __isnormalf ( float x )
{
- unsigned long int iexp;
+ unsigned int iexp;
union {
- unsigned long int lval;
+ u_int32_t lval;
float fval;
} z;
@@ -133,14 +132,14 @@ long int __isnormalf ( float x )
}
-long int __isnorma ( double x )
+int __isnormal ( double x )
{
return ( __fpclassify ( x ) == FP_NORMAL );
}
/***********************************************************************
- long int __isfinitef(float x) returns nonzero if and only if x is a
+ int __isfinitef(float x) returns nonzero if and only if x is a
finite (normal, subnormal, or zero) float number and zero otherwise.
Exceptions: INVALID is raised if x is a signaling NaN; in this case,
@@ -149,10 +148,10 @@ long int __isnorma ( double x )
Calls: none
***********************************************************************/
-long int __finitef ( float x )
+int __finitef ( float x )
{
union {
- unsigned long int lval;
+ u_int32_t lval;
float fval;
} z;
@@ -160,14 +159,14 @@ long int __finitef ( float x )
return ((z.lval & FEXP_MASK) != FEXP_MASK);
}
-long int __finite ( double x )
+int __finite ( double x )
{
return ( __fpclassify ( x ) >= FP_ZERO );
}
/***********************************************************************
- long int __signbitf(float x) returns nonzero if and only if the sign
+ int __signbitf(float x) returns nonzero if and only if the sign
bit of x is set and zero otherwise.
Exceptions: INVALID is raised if x is a signaling NaN.
@@ -175,10 +174,10 @@ long int __finite ( double x )
Calls: none
***********************************************************************/
-long int __signbitf ( float x )
+int __signbitf ( float x )
{
union {
- unsigned long int lval;
+ u_int32_t lval;
float fval;
} z;
@@ -194,14 +193,14 @@ long int __signbitf ( float x )
Calls: none
***********************************************************************/
-long int __signbit ( double arg )
+int __signbit ( double arg )
{
union
{
dHexParts hex;
double dbl;
} x;
- long int sign;
+ int sign;
x.dbl = arg;
sign = ( ( x.hex.high & dSgnMask ) == dSgnMask ) ? 1 : 0;
@@ -210,15 +209,15 @@ long int __signbit ( double arg )
/***********************************************************************
-* long int __isinff(float x) returns -1 if value represents negative
+* int __isinff(float x) returns -1 if value represents negative
* infinity, 1 if value represents positive infinity,
* and 0 otherwise.
*
* Calls: __signbit
* +***********************************************************************/
-long int __isinff ( float x )
+int __isinff ( float x )
{
- long int class = __fpclassifyf(x);
+ int class = __fpclassifyf(x);
if ( class == FP_INFINITE ) {
return ( (__signbitf(x)) ? -1 : 1);
}
@@ -226,9 +225,9 @@ long int __isinff ( float x )
}
weak_alias (__isinff, isinff)
-long int __isinf ( double x )
+int __isinf ( double x )
{
- long int class = __fpclassify(x);
+ int class = __fpclassify(x);
if ( class == FP_INFINITE ) {
return ( (__signbit(x)) ? -1 : 1);
}
@@ -237,21 +236,19 @@ long int __isinf ( double x )
weak_alias (__isinf, isinf)
#if 0
-long int __isinfl ( long double x )
+int __isinfl ( long double x )
{
- long int class = __fpclassify(x);
+ int class = __fpclassify(x);
if ( class == FP_INFINITE ) {
return ( (__signbit(x)) ? -1 : 1);
}
return 0;
}
weak_alias (__isinfl, isinfl);
-#else
-weak_alias (__isinf, isinfl)
#endif
/***********************************************************************
- long int __isnanf(float x) returns nonzero if and only if x is a
+ int __isnanf(float x) returns nonzero if and only if x is a
NaN and zero otherwise.
Exceptions: INVALID is raised if x is a signaling NaN; in this case,
@@ -260,10 +257,10 @@ weak_alias (__isinf, isinfl)
Calls: none
***********************************************************************/
-long int __isnanf ( float x )
+int __isnanf ( float x )
{
union {
- unsigned long int lval;
+ u_int32_t lval;
float fval;
} z;
@@ -272,21 +269,19 @@ long int __isnanf ( float x )
}
weak_alias (__isnanf, isnanf);
-long int __isnan ( double x )
+int __isnan ( double x )
{
- long int class = __fpclassify(x);
- return ( ( class == FP_SNAN ) || ( class == FP_QNAN ) );
+ int class = __fpclassify(x);
+ return ( class == FP_NAN );
}
weak_alias (__isnan, isnan);
#if 0
-long int __isnanl ( long double x )
+int __isnanl ( long double x )
{
- long int class = __fpclassify(x);
- return ( ( class == FP_SNAN ) || ( class == FP_QNAN ) );
+ int class = __fpclassify(x);
+ return ( class == FP_NAN );
}
weak_alias (__isnanl, isnanl);
-#else
-weak_alias (__isnan, isnanl);
#endif