>
> 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.
>
> Index: src/ld80/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
> --- src/ld80/s_nextafterl.c 12 Nov 2013 21:07:28 -0000 1.4
> +++ src/ld80/s_nextafterl.c 2 Jun 2014 13:21:58 -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,50 @@ 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 <= 0x80000000) {
> + if (esx == 0) {
> + --hx;
> + } else {
> + esx -= 1;
> + hx = hx - 1;
> + if (esx > 0)
> + hx |= 0x80000000;
> + }
> + } else
> + hx -= 1;
> }
> lx -= 1;
> } else { /* x < y, x += ulp */
> lx += 1;
> if(lx==0) {
> hx += 1;
> - if (hx==0)
> + 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)))))){
> /* x < y, x -= ulp */
> if(lx==0) {
> - if (hx==0) esx -= 1;
> - hx -= 1;
> + if (hx <= 0x80000000) {
> + esx -= 1;
> + hx = hx - 1;
> + if ((esx&0x7fff) > 0)
> + hx |= 0x80000000;
> + } else
> + hx -= 1;
> }
> lx -= 1;
> } else { /* x > y, x += ulp */
> lx += 1;
> if(lx==0) {
> hx += 1;
> - if (hx==0) esx += 1;
> + if (hx==0 || (esx == 0xffff8000 && hx == 0x80000000)) {
> + esx += 1;
> + hx |= 0x80000000;
> + }
> }
> }
> }