about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--math/test-misc.c488
-rw-r--r--sysdeps/i386/fpu/s_nextafterl.c16
2 files changed, 498 insertions, 6 deletions
diff --git a/math/test-misc.c b/math/test-misc.c
index 1c9c2a514c..1ba2943a5a 100644
--- a/math/test-misc.c
+++ b/math/test-misc.c
@@ -223,7 +223,146 @@ main (void)
 	printf ("fpclassify (-FLT_MAX-epsilon) failed: %d\n", fpclassify (f));
 	result = 1;
       }
+
+    v1.f = f = 0.0625;
+    f = nextafterf (f, 0.0);
+    v2.f = f = nextafterf (f, 1.0);
+
+    if (v1.ieee.mantissa != v2.ieee.mantissa)
+      {
+	printf ("0.0625f down: mantissa differs: %8x vs %8x\n",
+		v1.ieee.mantissa, v2.ieee.mantissa);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0625f down: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("0.0625f down: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.f = f = 0.0625;
+    f = nextafterf (f, 1.0);
+    v2.f = f = nextafterf (f, 0.0);
+
+    if (v1.ieee.mantissa != v2.ieee.mantissa)
+      {
+	printf ("0.0625f up: mantissa differs: %8x vs %8x\n",
+		v1.ieee.mantissa, v2.ieee.mantissa);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0625f up: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("0.0625f up: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.f = f = -0.0625;
+    f = nextafterf (f, 0.0);
+    v2.f = f = nextafterf (f, -1.0);
+
+    if (v1.ieee.mantissa != v2.ieee.mantissa)
+      {
+	printf ("-0.0625f up: mantissa differs: %8x vs %8x\n",
+		v1.ieee.mantissa, v2.ieee.mantissa);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("-0.0625f up: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("-0.0625f up: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.f = f = -0.0625;
+    f = nextafterf (f, -1.0);
+    v2.f = f = nextafterf (f, 0.0);
+
+    if (v1.ieee.mantissa != v2.ieee.mantissa)
+      {
+	printf ("-0.0625f down: mantissa differs: %8x vs %8x\n",
+		v1.ieee.mantissa, v2.ieee.mantissa);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("-0.0625f down: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("-0.0625f down: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.f = f = 0.0f;
+    f = nextafterf (f, 1.0);
+    v2.f = nextafterf (f, -1.0);
+
+    if (v1.ieee.mantissa != v2.ieee.mantissa)
+      {
+	printf ("0.0f up: mantissa differs: %8x vs %8x\n",
+		v1.ieee.mantissa, v2.ieee.mantissa);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0f up: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (0 != v2.ieee.negative)
+      {
+	printf ("0.0f up: negative differs: 0 vs %d\n",
+		v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.f = f = 0.0f;
+    f = nextafterf (f, -1.0);
+    v2.f = nextafterf (f, 1.0);
+
+    if (v1.ieee.mantissa != v2.ieee.mantissa)
+      {
+	printf ("0.0f down: mantissa differs: %8x vs %8x\n",
+		v1.ieee.mantissa, v2.ieee.mantissa);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0f down: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (1 != v2.ieee.negative)
+      {
+	printf ("0.0f down: negative differs: 1 vs %d\n",
+		v2.ieee.negative);
+	result = 1;
+      }
   }
+
   {
     union ieee754_double v1;
     union ieee754_double v2;
@@ -344,7 +483,182 @@ main (void)
 	printf ("fpclassify (-DBL_MAX-epsilon) failed: %d\n", fpclassify (d));
 	result = 1;
       }
+
+    v1.d = d = 0.0625;
+    d = nextafter (d, 0.0);
+    v2.d = d = nextafter (d, 1.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("0.0625 down: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("0.0625 down: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0625 down: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("0.0625 down: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = d = 0.0625;
+    d = nextafter (d, 1.0);
+    v2.d = d = nextafter (d, 0.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("0.0625 up: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("0.0625 up: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0625 up: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("0.0625 up: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = d = -0.0625;
+    d = nextafter (d, 0.0);
+    v2.d = d = nextafter (d, -1.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("-0.0625 up: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("-0.0625 up: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("-0.0625 up: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("-0.0625 up: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = d = -0.0625;
+    d = nextafter (d, -1.0);
+    v2.d = d = nextafter (d, 0.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("-0.0625 down: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("-0.0625 down: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("-0.0625 down: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("-0.0625 down: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = d = 0.0;
+    d = nextafter (d, 1.0);
+    v2.d = nextafter (d, -1.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("0.0 up: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("0.0 up: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0 up: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (0 != v2.ieee.negative)
+      {
+	printf ("0.0 up: negative differs: 0 vs %d\n",
+		v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = d = 0.0;
+    d = nextafter (d, -1.0);
+    v2.d = nextafter (d, 1.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("0.0 down: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("0.0 down: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0 down: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (1 != v2.ieee.negative)
+      {
+	printf ("0.0 down: negative differs: 1 vs %d\n",
+		v2.ieee.negative);
+	result = 1;
+      }
   }
+
 #ifndef NO_LONG_DOUBLE
   {
     union ieee854_long_double v1;
@@ -469,6 +783,180 @@ main (void)
 		fpclassify (ld));
 	result = 1;
       }
+
+    v1.d = ld = 0.0625;
+    ld = nextafterl (ld, 0.0);
+    v2.d = ld = nextafterl (ld, 1.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("0.0625L down: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("0.0625L down: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0625L down: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("0.0625L down: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = ld = 0.0625;
+    ld = nextafterl (ld, 1.0);
+    v2.d = ld = nextafterl (ld, 0.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("0.0625L up: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("0.0625L up: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0625L up: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("0.0625L up: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = ld = -0.0625;
+    ld = nextafterl (ld, 0.0);
+    v2.d = ld = nextafterl (ld, -1.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("-0.0625L up: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("-0.0625L up: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("-0.0625L up: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("-0.0625L up: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = ld = -0.0625;
+    ld = nextafterl (ld, -1.0);
+    v2.d = ld = nextafterl (ld, 0.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("-0.0625L down: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("-0.0625L down: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("-0.0625L down: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (v1.ieee.negative != v2.ieee.negative)
+      {
+	printf ("-0.0625L down: negative differs: %d vs %d\n",
+		v1.ieee.negative, v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = ld = 0.0;
+    ld = nextafterl (ld, 1.0);
+    v2.d = nextafterl (ld, -1.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("0.0L up: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("0.0L up: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0L up: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (0 != v2.ieee.negative)
+      {
+	printf ("0.0L up: negative differs: 0 vs %d\n",
+		v2.ieee.negative);
+	result = 1;
+      }
+
+    v1.d = ld = 0.0;
+    ld = nextafterl (ld, -1.0);
+    v2.d = nextafterl (ld, 1.0);
+
+    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+      {
+	printf ("0.0L down: mantissa0 differs: %8x vs %8x\n",
+		v1.ieee.mantissa0, v2.ieee.mantissa0);
+	result = 1;
+      }
+    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+      {
+	printf ("0.0L down: mantissa1 differs: %8x vs %8x\n",
+		v1.ieee.mantissa1, v2.ieee.mantissa1);
+	result = 1;
+      }
+    if (v1.ieee.exponent != v2.ieee.exponent)
+      {
+	printf ("0.0L down: exponent differs: %4x vs %4x\n",
+		v1.ieee.exponent, v2.ieee.exponent);
+	result = 1;
+      }
+    if (1 != v2.ieee.negative)
+      {
+	printf ("0.0L down: negative differs: 1 vs %d\n",
+		v2.ieee.negative);
+	result = 1;
+      }
   }
 #endif
 
diff --git a/sysdeps/i386/fpu/s_nextafterl.c b/sysdeps/i386/fpu/s_nextafterl.c
index 89adf04aec..b99914700c 100644
--- a/sysdeps/i386/fpu/s_nextafterl.c
+++ b/sysdeps/i386/fpu/s_nextafterl.c
@@ -52,12 +52,12 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if(x==y) return y;		/* x=y, return y */
 	if((ix|hx|lx)==0) {			/* x == 0 */
-	    SET_LDOUBLE_WORDS(x,esx&0x8000,0,1);/* return +-minsubnormal */
+	    SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
 	    y = x*x;
 	    if(y==x) return y; else return x;	/* raise underflow flag */
 	}
 	if(esx>=0) {			/* x > 0 */
-	    if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
+	    if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
 	      /* x > y, x -= ulp */
 		if(lx==0) {
 		    if (hx <= 0x80000000) {
@@ -77,12 +77,14 @@ static char rcsid[] = "$NetBSD: $";
 		lx += 1;
 		if(lx==0) {
 		    hx += 1;
-		    if (hx==0 || (esx == 0 && hx == 0x80000000))
+		    if (hx==0 || (esx == 0 && hx == 0x80000000)) {
 			esx += 1;
+			hx |= 0x80000000;
+		    }
 		}
 	    }
 	} else {				/* x < 0 */
-	    if(esy>=0||(ix>iy||((ix==iy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){
+	    if(esy>=0||(esx>esy||((esx==esy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){
 	      /* x < y, x -= ulp */
 		if(lx==0) {
 		    if (hx <= 0x80000000) {
@@ -102,8 +104,10 @@ static char rcsid[] = "$NetBSD: $";
 		lx += 1;
 		if(lx==0) {
 		    hx += 1;
-		    if (hx==0 || (esx == 0xffff8000 && hx == 0x80000000))
-		      esx += 1;
+		    if (hx==0 || (esx == 0xffff8000 && hx == 0x80000000)) {
+			esx += 1;
+			hx |= 0x80000000;
+		    }
 		}
 	    }
 	}