> Date: Mon, 2 Jun 2014 21:18:26 -0400
> From: Daniel Dickman <[email protected]>
>
> >
> > 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;
}
}
}