On 6/4/14, Mark Kettenis <mark.kette...@xs4all.nl> wrote: >> 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?
I like it better than the other diff; OK martynas@. > 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; > } > } > } >