diff options
author | Stefan Farfeleder <stefanf@FreeBSD.org> | 2005-04-22 08:30:33 +0000 |
---|---|---|
committer | Stefan Farfeleder <stefanf@FreeBSD.org> | 2005-04-22 08:30:33 +0000 |
commit | 9eb30792de62cc44811f407e055ac18d95ecf247 (patch) | |
tree | 98d93b888d7f38495710281c3cc30696bf47dd2e /lib/msun | |
parent | c4bb0466ff0880466861a648f6af7bef63b4a2f2 (diff) | |
download | src-9eb30792de62cc44811f407e055ac18d95ecf247.tar.gz src-9eb30792de62cc44811f407e055ac18d95ecf247.zip |
Fix raising the inexact exception (FE_INEXACT) if the result differs from the
argument.
Noticed by: das
Notes
Notes:
svn path=/head/; revision=145394
Diffstat (limited to 'lib/msun')
-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 92f50337ce8d..1de973b0f62d 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 571d26c9c95d..9dd13b6cb1cc 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 d535e9cac92e..c475b904dccf 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); } |