summaryrefslogtreecommitdiffstats
path: root/lib/msun/src/s_fmal.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/msun/src/s_fmal.c')
-rw-r--r--lib/msun/src/s_fmal.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/msun/src/s_fmal.c b/lib/msun/src/s_fmal.c
index 1604778..4d5d114 100644
--- a/lib/msun/src/s_fmal.c
+++ b/lib/msun/src/s_fmal.c
@@ -55,14 +55,19 @@ fmal(long double x, long double y, long double z)
int ex, ey, ez;
int spread;
- if (z == 0.0)
- return (x * y);
+ /*
+ * Handle special cases. The order of operations and the particular
+ * return values here are crucial in handling special cases involving
+ * infinities, NaNs, overflows, and signed zeroes correctly.
+ */
if (x == 0.0 || y == 0.0)
return (x * y + z);
-
- /* Results of frexp() are undefined for these cases. */
- if (!isfinite(x) || !isfinite(y) || !isfinite(z))
+ if (z == 0.0)
+ return (x * y);
+ if (!isfinite(x) || !isfinite(y))
return (x * y + z);
+ if (!isfinite(z))
+ return (z);
xs = frexpl(x, &ex);
ys = frexpl(y, &ey);
OpenPOWER on IntegriCloud