summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstefanf <stefanf@FreeBSD.org>2005-04-22 08:30:33 +0000
committerstefanf <stefanf@FreeBSD.org>2005-04-22 08:30:33 +0000
commit77782516eb51b13ce913730d6522843721cef913 (patch)
tree98d93b888d7f38495710281c3cc30696bf47dd2e
parent1d4ca8df02da84a302dfdd9feae99371773c0c6a (diff)
downloadFreeBSD-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.c19
-rw-r--r--lib/msun/src/s_floorl.c19
-rw-r--r--lib/msun/src/s_truncl.c14
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);
}
OpenPOWER on IntegriCloud