about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--math/test-misc.c169
-rw-r--r--sysdeps/i386/fpu/s_nextafterl.c7
3 files changed, 169 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 7a8b75beab..6a7fe3b245 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2000-12-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* math/test-misc.c: Add more tests for nextafter functions.
+
+	* sysdeps/i386/fpu/s_nextafterl.c: Handle change from denormal to
+	normal correctly.  Correct test for sign.
+	Based on a patch by HJ Lu.
+
 2000-12-19  Ulrich Drepper  <drepper@redhat.com>
 
 	* Makeconfig (preprocess-version): Add -traditional to gcc call.
diff --git a/math/test-misc.c b/math/test-misc.c
index 524644d5bd..1c9c2a514c 100644
--- a/math/test-misc.c
+++ b/math/test-misc.c
@@ -18,6 +18,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <fenv.h>
+#include <ieee754.h>
 #include <math.h>
 #include <stdio.h>
 #include <string.h>
@@ -115,9 +116,11 @@ main (void)
   }
 
   {
+    union ieee754_float v1;
+    union ieee754_float v2;
     float f;
 
-    f = FLT_MIN;
+    v1.f = f = FLT_MIN;
     if (fpclassify (f) != FP_NORMAL)
       {
 	printf ("fpclassify (FLT_MIN) failed: %d\n", fpclassify (f));
@@ -129,7 +132,7 @@ main (void)
 	printf ("fpclassify (FLT_MIN-epsilon) failed: %d\n", fpclassify (f));
 	result = 1;
       }
-    f = nextafterf (f, FLT_MIN);
+    v2.f = f = nextafterf (f, FLT_MIN);
     if (fpclassify (f) != FP_NORMAL)
       {
 	printf ("fpclassify (FLT_MIN-epsilon+epsilon) failed: %d\n",
@@ -137,7 +140,26 @@ main (void)
 	result = 1;
       }
 
-    f = -FLT_MIN;
+    if (v1.ieee.mantissa != v2.ieee.mantissa)
+      {
+	printf ("FLT_MIN: mantissa differs: %8x vs %8x\n",
+		v1.ieee.mantissa, v2.ieee.mantissa);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("FLT_MIN: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("FLT_MIN: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.f = f = -FLT_MIN;
     if (fpclassify (f) != FP_NORMAL)
       {
 	printf ("fpclassify (-FLT_MIN) failed: %d\n", fpclassify (f));
@@ -149,7 +171,7 @@ main (void)
 	printf ("fpclassify (-FLT_MIN-epsilon) failed: %d\n", fpclassify (f));
 	result = 1;
       }
-    f = nextafterf (f, -FLT_MIN);
+    v2.f = f = nextafterf (f, -FLT_MIN);
     if (fpclassify (f) != FP_NORMAL)
       {
 	printf ("fpclassify (-FLT_MIN-epsilon+epsilon) failed: %d\n",
@@ -157,6 +179,25 @@ main (void)
 	result = 1;
       }
 
+    if (v1.ieee.mantissa != v2.ieee.mantissa)
+      {
+	printf ("-FLT_MIN: mantissa differs: %8x vs %8x\n",
+		v1.ieee.mantissa, v2.ieee.mantissa);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("-FLT_MIN: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("-FLT_MIN: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
     f = FLT_MAX;
     if (fpclassify (f) != FP_NORMAL)
       {
@@ -184,9 +225,11 @@ main (void)
       }
   }
   {
+    union ieee754_double v1;
+    union ieee754_double v2;
     double d;
 
-    d = DBL_MIN;
+    v1.d = d = DBL_MIN;
     if (fpclassify (d) != FP_NORMAL)
       {
 	printf ("fpclassify (DBL_MIN) failed: %d\n", fpclassify (d));
@@ -198,7 +241,7 @@ main (void)
 	printf ("fpclassify (DBL_MIN-epsilon) failed: %d\n", fpclassify (d));
 	result = 1;
       }
-    d = nextafter (d, DBL_MIN);
+    v2.d = d = nextafter (d, DBL_MIN);
     if (fpclassify (d) != FP_NORMAL)
       {
 	printf ("fpclassify (DBL_MIN-epsilon+epsilon) failed: %d\n",
@@ -206,7 +249,32 @@ main (void)
 	result = 1;
       }
 
-    d = -DBL_MIN;
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("DBL_MIN: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("DBL_MIN: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("DBL_MIN: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("DBL_MIN: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = d = -DBL_MIN;
     if (fpclassify (d) != FP_NORMAL)
       {
 	printf ("fpclassify (-DBL_MIN) failed: %d\n", fpclassify (d));
@@ -218,7 +286,7 @@ main (void)
 	printf ("fpclassify (-DBL_MIN-epsilon) failed: %d\n", fpclassify (d));
 	result = 1;
       }
-    d = nextafter (d, -DBL_MIN);
+    v2.d = d = nextafter (d, -DBL_MIN);
     if (fpclassify (d) != FP_NORMAL)
       {
 	printf ("fpclassify (-DBL_MIN-epsilon+epsilon) failed: %d\n",
@@ -226,6 +294,31 @@ main (void)
 	result = 1;
       }
 
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("-DBL_MIN: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("-DBL_MIN: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("-DBL_MIN: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("-DBL_MIN: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
     d = DBL_MAX;
     if (fpclassify (d) != FP_NORMAL)
       {
@@ -254,9 +347,11 @@ main (void)
   }
 #ifndef NO_LONG_DOUBLE
   {
+    union ieee854_long_double v1;
+    union ieee854_long_double v2;
     long double ld;
 
-    ld = LDBL_MIN;
+    v1.d = ld = LDBL_MIN;
     if (fpclassify (ld) != FP_NORMAL)
       {
 	printf ("fpclassify (LDBL_MIN) failed: %d\n", fpclassify (ld));
@@ -269,7 +364,7 @@ main (void)
 		fpclassify (ld), ld);
 	result = 1;
       }
-    ld = nextafterl (ld, LDBL_MIN);
+    v2.d = ld = nextafterl (ld, LDBL_MIN);
     if (fpclassify (ld) != FP_NORMAL)
       {
 	printf ("fpclassify (LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n",
@@ -277,7 +372,32 @@ main (void)
 	result = 1;
       }
 
-    ld = -LDBL_MIN;
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("LDBL_MIN: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("LDBL_MIN: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("LDBL_MIN: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("LDBL_MIN: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = ld = -LDBL_MIN;
     if (fpclassify (ld) != FP_NORMAL)
       {
 	printf ("fpclassify (-LDBL_MIN) failed: %d\n", fpclassify (ld));
@@ -290,7 +410,7 @@ main (void)
 		fpclassify (ld), ld);
 	result = 1;
       }
-    ld = nextafterl (ld, -LDBL_MIN);
+    v2.d = ld = nextafterl (ld, -LDBL_MIN);
     if (fpclassify (ld) != FP_NORMAL)
       {
 	printf ("fpclassify (-LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n",
@@ -298,6 +418,31 @@ main (void)
 	result = 1;
       }
 
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("-LDBL_MIN: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("-LDBL_MIN: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("-LDBL_MIN: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("-LDBL_MIN: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
     ld = LDBL_MAX;
     if (fpclassify (ld) != FP_NORMAL)
       {
diff --git a/sysdeps/i386/fpu/s_nextafterl.c b/sysdeps/i386/fpu/s_nextafterl.c
index 2943a613e3..89adf04aec 100644
--- a/sysdeps/i386/fpu/s_nextafterl.c
+++ b/sysdeps/i386/fpu/s_nextafterl.c
@@ -56,7 +56,7 @@ static char rcsid[] = "$NetBSD: $";
 	    y = x*x;
 	    if(y==x) return y; else return x;	/* raise underflow flag */
 	}
-	if(esx<0x8000) {			/* x > 0 */
+	if(esx>=0) {			/* x > 0 */
 	    if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
 	      /* x > y, x -= ulp */
 		if(lx==0) {
@@ -77,7 +77,7 @@ static char rcsid[] = "$NetBSD: $";
 		lx += 1;
 		if(lx==0) {
 		    hx += 1;
-		    if (hx==0)
+		    if (hx==0 || (esx == 0 && hx == 0x80000000))
 			esx += 1;
 		}
 	    }
@@ -102,7 +102,8 @@ static char rcsid[] = "$NetBSD: $";
 		lx += 1;
 		if(lx==0) {
 		    hx += 1;
-		    if (hx==0) esx += 1;
+		    if (hx==0 || (esx == 0xffff8000 && hx == 0x80000000))
+		      esx += 1;
 		}
 	    }
 	}