> 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; } } }