diff options
author | Joseph Myers <joseph@codesourcery.com> | 2012-11-04 19:26:02 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2012-11-04 19:26:02 +0000 |
commit | a0c2940d67e59b2f19515e2ac7280a7be9629ffa (patch) | |
tree | 7827ebc10a3baa4a0418e12a2d28c666d0b157bd /sysdeps/ieee754 | |
parent | b830319d49a421741b61ae29ce32ab37f8b970ed (diff) | |
download | glibc-a0c2940d67e59b2f19515e2ac7280a7be9629ffa.tar.gz glibc-a0c2940d67e59b2f19515e2ac7280a7be9629ffa.tar.xz glibc-a0c2940d67e59b2f19515e2ac7280a7be9629ffa.zip |
Fix fma overflow results outside round-to-nearest mode (bug 14797).
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r-- | sysdeps/ieee754/dbl-64/s_fma.c | 9 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_fmal.c | 10 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/s_fmal.c | 10 |
3 files changed, 17 insertions, 12 deletions
diff --git a/sysdeps/ieee754/dbl-64/s_fma.c b/sysdeps/ieee754/dbl-64/s_fma.c index 07fe715617..cd28830709 100644 --- a/sysdeps/ieee754/dbl-64/s_fma.c +++ b/sysdeps/ieee754/dbl-64/s_fma.c @@ -55,16 +55,17 @@ __fma (double x, double y, double z) underflows to 0. */ if (z == 0 && x != 0 && y != 0) return x * y; - /* If x or y or z is Inf/NaN, or if fma will certainly overflow, - or if x * y is zero, compute as x * y + z. */ + /* If x or y or z is Inf/NaN, or if x * y is zero, compute as + x * y + z. */ if (u.ieee.exponent == 0x7ff || v.ieee.exponent == 0x7ff || w.ieee.exponent == 0x7ff - || u.ieee.exponent + v.ieee.exponent - > 0x7ff + IEEE754_DOUBLE_BIAS || x == 0 || y == 0) return x * y + z; + /* If fma will certainly overflow, compute as x * y. */ + if (u.ieee.exponent + v.ieee.exponent > 0x7ff + IEEE754_DOUBLE_BIAS) + return x * y; /* If x * y is less than 1/4 of DBL_DENORM_MIN, neither the result nor whether there is underflow depends on its exact value, only on its sign. */ diff --git a/sysdeps/ieee754/ldbl-128/s_fmal.c b/sysdeps/ieee754/ldbl-128/s_fmal.c index d576403b25..6fa663a6c0 100644 --- a/sysdeps/ieee754/ldbl-128/s_fmal.c +++ b/sysdeps/ieee754/ldbl-128/s_fmal.c @@ -56,16 +56,18 @@ __fmal (long double x, long double y, long double z) underflows to 0. */ if (z == 0 && x != 0 && y != 0) return x * y; - /* If x or y or z is Inf/NaN, or if fma will certainly overflow, - or if x * y is zero, compute as x * y + z. */ + /* If x or y or z is Inf/NaN, or if x * y is zero, compute as + x * y + z. */ if (u.ieee.exponent == 0x7fff || v.ieee.exponent == 0x7fff || w.ieee.exponent == 0x7fff - || u.ieee.exponent + v.ieee.exponent - > 0x7fff + IEEE854_LONG_DOUBLE_BIAS || x == 0 || y == 0) return x * y + z; + /* If fma will certainly overflow, compute as x * y. */ + if (u.ieee.exponent + v.ieee.exponent + > 0x7fff + IEEE854_LONG_DOUBLE_BIAS) + return x * y; /* If x * y is less than 1/4 of LDBL_DENORM_MIN, neither the result nor whether there is underflow depends on its exact value, only on its sign. */ diff --git a/sysdeps/ieee754/ldbl-96/s_fmal.c b/sysdeps/ieee754/ldbl-96/s_fmal.c index 32e71a18ba..53098b6d4e 100644 --- a/sysdeps/ieee754/ldbl-96/s_fmal.c +++ b/sysdeps/ieee754/ldbl-96/s_fmal.c @@ -56,16 +56,18 @@ __fmal (long double x, long double y, long double z) underflows to 0. */ if (z == 0 && x != 0 && y != 0) return x * y; - /* If x or y or z is Inf/NaN, or if fma will certainly overflow, - or if x * y is zero, compute as x * y + z. */ + /* If x or y or z is Inf/NaN, or if x * y is zero, compute as + x * y + z. */ if (u.ieee.exponent == 0x7fff || v.ieee.exponent == 0x7fff || w.ieee.exponent == 0x7fff - || u.ieee.exponent + v.ieee.exponent - > 0x7fff + IEEE854_LONG_DOUBLE_BIAS || x == 0 || y == 0) return x * y + z; + /* If fma will certainly overflow, compute as x * y. */ + if (u.ieee.exponent + v.ieee.exponent + > 0x7fff + IEEE854_LONG_DOUBLE_BIAS) + return x * y; /* If x * y is less than 1/4 of LDBL_DENORM_MIN, neither the result nor whether there is underflow depends on its exact value, only on its sign. */ |