summaryrefslogtreecommitdiffstats
path: root/lib/libm/src
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2014-06-05 08:21:30 +0000
committerkettenis <kettenis@openbsd.org>2014-06-05 08:21:30 +0000
commit0b84a240e5db06112cea6cac93dcfc5b5577b54f (patch)
tree12e44922f4da2bd7012f254a3f219f87dd0550b0 /lib/libm/src
parentAdd support for COLUMNS env variable, inspired by FreeBSD but with a dash (diff)
downloadwireguard-openbsd-0b84a240e5db06112cea6cac93dcfc5b5577b54f.tar.xz
wireguard-openbsd-0b84a240e5db06112cea6cac93dcfc5b5577b54f.zip
Extended precision floating-point numbers have an explicit integer part bit.
Correctly account for this bit, otherwise we'll get the wrong result for some inputs. ok martynas@, daniel@
Diffstat (limited to 'lib/libm/src')
-rw-r--r--lib/libm/src/ld80/s_nextafterl.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/lib/libm/src/ld80/s_nextafterl.c b/lib/libm/src/ld80/s_nextafterl.c
index 9187e44f7bf..0c28b02101e 100644
--- a/lib/libm/src/ld80/s_nextafterl.c
+++ b/lib/libm/src/ld80/s_nextafterl.c
@@ -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;
}
}
}