diff options
author | stefanf <stefanf@FreeBSD.org> | 2005-04-22 08:30:33 +0000 |
---|---|---|
committer | stefanf <stefanf@FreeBSD.org> | 2005-04-22 08:30:33 +0000 |
commit | 77782516eb51b13ce913730d6522843721cef913 (patch) | |
tree | 98d93b888d7f38495710281c3cc30696bf47dd2e | |
parent | 1d4ca8df02da84a302dfdd9feae99371773c0c6a (diff) | |
download | FreeBSD-src-77782516eb51b13ce913730d6522843721cef913.zip FreeBSD-src-77782516eb51b13ce913730d6522843721cef913.tar.gz |
Fix raising the inexact exception (FE_INEXACT) if the result differs from the
argument.
Noticed by: das
-rw-r--r-- | lib/msun/src/s_ceill.c | 19 | ||||
-rw-r--r-- | lib/msun/src/s_floorl.c | 19 | ||||
-rw-r--r-- | lib/msun/src/s_truncl.c | 14 |
3 files changed, 34 insertions, 18 deletions
diff --git a/lib/msun/src/s_ceill.c b/lib/msun/src/s_ceill.c index 92f5033..1de973b 100644 --- a/lib/msun/src/s_ceill.c +++ b/lib/msun/src/s_ceill.c @@ -50,6 +50,8 @@ static char rcsid[] = "$FreeBSD$"; } while (0) #endif +static const long double huge = 1.0e300; + long double ceill(long double x) { @@ -58,13 +60,14 @@ ceill(long double x) if (e < MANH_SIZE - 1) { if (e < 0) { /* raise inexact if x != 0 */ - if (u.bits.exp > 0 || (u.bits.manh | u.bits.manl) != 0) - u.e = u.bits.sign ? 0.0 : 1.0; + if (huge + x > 0.0) + if (u.bits.exp > 0 || + (u.bits.manh | u.bits.manl) != 0) + u.e = u.bits.sign ? 0.0 : 1.0; } else { uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); if (((u.bits.manh & m) | u.bits.manl) == 0) return (x); /* x is integral */ - /* raise inexact flag */ if (!u.bits.sign) { #ifdef LDBL_IMPLICIT_NBIT if (e == 0) @@ -73,14 +76,15 @@ ceill(long double x) #endif INC_MANH(u, 1llu << (MANH_SIZE - e - 1)); } - u.bits.manh &= ~m; - u.bits.manl = 0; + if (huge + x > 0.0) { /* raise inexact flag */ + u.bits.manh &= ~m; + u.bits.manl = 0; + } } } else if (e < LDBL_MANT_DIG - 1) { uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); if ((u.bits.manl & m) == 0) return (x); /* x is integral */ - /* raise inexact flag */ if (!u.bits.sign) { if (e == MANH_SIZE - 1) INC_MANH(u, 1); @@ -91,7 +95,8 @@ ceill(long double x) INC_MANH(u, 1); } } - u.bits.manl &= ~m; + if (huge + x > 0.0) /* raise inexact flag */ + u.bits.manl &= ~m; } return (u.e); } diff --git a/lib/msun/src/s_floorl.c b/lib/msun/src/s_floorl.c index 571d26c..9dd13b6 100644 --- a/lib/msun/src/s_floorl.c +++ b/lib/msun/src/s_floorl.c @@ -50,6 +50,8 @@ static char rcsid[] = "$FreeBSD$"; } while (0) #endif +static const long double huge = 1.0e300; + long double floorl(long double x) { @@ -58,13 +60,14 @@ floorl(long double x) if (e < MANH_SIZE - 1) { if (e < 0) { /* raise inexact if x != 0 */ - if (u.bits.exp > 0 || (u.bits.manh | u.bits.manl) != 0) - u.e = u.bits.sign ? -1.0 : 0.0; + if (huge + x > 0.0) + if (u.bits.exp > 0 || + (u.bits.manh | u.bits.manl) != 0) + u.e = u.bits.sign ? -1.0 : 0.0; } else { uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); if (((u.bits.manh & m) | u.bits.manl) == 0) return (x); /* x is integral */ - /* raise inexact flag */ if (u.bits.sign) { #ifdef LDBL_IMPLICIT_NBIT if (e == 0) @@ -73,14 +76,15 @@ floorl(long double x) #endif INC_MANH(u, 1llu << (MANH_SIZE - e - 1)); } - u.bits.manh &= ~m; - u.bits.manl = 0; + if (huge + x > 0.0) { /* raise inexact flag */ + u.bits.manh &= ~m; + u.bits.manl = 0; + } } } else if (e < LDBL_MANT_DIG - 1) { uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); if ((u.bits.manl & m) == 0) return (x); /* x is integral */ - /* raise inexact flag */ if (u.bits.sign) { if (e == MANH_SIZE - 1) INC_MANH(u, 1); @@ -91,7 +95,8 @@ floorl(long double x) INC_MANH(u, 1); } } - u.bits.manl &= ~m; + if (huge + x > 0.0) /* raise inexact flag */ + u.bits.manl &= ~m; } return (u.e); } diff --git a/lib/msun/src/s_truncl.c b/lib/msun/src/s_truncl.c index d535e9c..c475b90 100644 --- a/lib/msun/src/s_truncl.c +++ b/lib/msun/src/s_truncl.c @@ -36,6 +36,8 @@ static char rcsid[] = "$FreeBSD$"; #define MANH_SIZE LDBL_MANH_SIZE #endif +static const long double huge = 1.0e300; + long double truncl(long double x) { @@ -44,19 +46,23 @@ truncl(long double x) if (e < MANH_SIZE - 1) { if (e < 0) { /* raise inexact if x != 0 */ - u.e = 0.0; + if (huge + x > 0.0) + u.e = 0.0; } else { uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); if (((u.bits.manh & m) | u.bits.manl) == 0) return (x); /* x is integral */ - u.bits.manh &= ~m; - u.bits.manl = 0; + if (huge + x > 0.0) { /* raise inexact flag */ + u.bits.manh &= ~m; + u.bits.manl = 0; + } } } else if (e < LDBL_MANT_DIG - 1) { uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); if ((u.bits.manl & m) == 0) return (x); /* x is integral */ - u.bits.manl &= ~m; + if (huge + x > 0.0) /* raise inexact flag */ + u.bits.manl &= ~m; } return (u.e); } |