> Date: Mon, 2 Jun 2014 21:18:26 -0400
> From: Daniel Dickman <didick...@gmail.com>
> 
> >
> > Another bug.  Intel chose an extended precision format with an
> > explicit integer bit, and the code doesn't handle that.  Assuming we
> > don't support machines with extended precision format that have an
> > implicit integer bit, the following diff (an adaptation of the code in
> > glibc) should fix things.  Not entirely happy with the fix though, so
> > I'm still thinking about improvements.
> 
> confirming that this patch fixes the failing numpy regress test on i386.
> 
> let me know if you want me to test a different diff.

Here's a better diff, inspired by what FreeBSD has.

ok?


Index: s_nextafterl.c
===================================================================
RCS file: /cvs/src/lib/libm/src/ld80/s_nextafterl.c,v
retrieving revision 1.4
diff -u -p -r1.4 s_nextafterl.c
--- s_nextafterl.c      12 Nov 2013 21:07:28 -0000      1.4
+++ s_nextafterl.c      4 Jun 2014 10:05:17 -0000
@@ -32,8 +32,8 @@ nextafterl(long double x, long double y)
        ix = esx&0x7fff;                /* |x| */
        iy = esy&0x7fff;                /* |y| */
 
-       if (((ix==0x7fff)&&((hx|lx)!=0)) ||   /* x is nan */
-           ((iy==0x7fff)&&((hy|ly)!=0)))     /* y is nan */
+       if (((ix==0x7fff)&&((hx&0x7fffffff|lx)!=0)) ||   /* x is nan */
+           ((iy==0x7fff)&&((hy&0x7fffffff|ly)!=0)))     /* y is nan */
           return x+y;
        if(x==y) return y;              /* x=y, return y */
        if((ix|hx|lx)==0) {                     /* x == 0 */
@@ -47,31 +47,30 @@ nextafterl(long double x, long double y)
            if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
              /* x > y, x -= ulp */
                if(lx==0) {
-                   if (hx==0) esx -= 1;
-                   hx -= 1;
+                   if ((hx&0x7fffffff)==0) esx -= 1;
+                   hx = (hx - 1) | (hx & 0x80000000);
                }
                lx -= 1;
            } else {                            /* x < y, x += ulp */
                lx += 1;
                if(lx==0) {
-                   hx += 1;
-                   if (hx==0)
-                       esx += 1;
+                   hx = (hx + 1) | (hx & 0x80000000);
+                   if ((hx&0x7fffffff)==0) esx += 1;
                }
            }
        } else {                                /* x < 0 */
            if(esy>=0||(ix>iy||((ix==iy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){
              /* x < y, x -= ulp */
                if(lx==0) {
-                   if (hx==0) esx -= 1;
-                   hx -= 1;
+                   if ((hx&0x7fffffff)==0) esx -= 1;
+                   hx = (hx - 1) | (hx & 0x80000000);
                }
                lx -= 1;
            } else {                            /* x > y, x += ulp */
                lx += 1;
                if(lx==0) {
-                   hx += 1;
-                   if (hx==0) esx += 1;
+                   hx = (hx + 1) | (hx & 0x80000000);
+                   if ((hx&0x7fffffff)==0) esx += 1;
                }
            }
        }

Reply via email to