aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSzabolcs Nagy <nsz@port70.net>2021-07-05 22:37:22 +0000
committerRich Felker <dalias@aerifal.cx>2021-07-06 00:29:57 -0400
commit4f3d346bffdf9ed2b1803653643dc31242490944 (patch)
treec89c3502fac36a715e2621aa1d0dc90344389bcd /src
parent937822abb6ac48880939be3c60e6b57bddf62cf6 (diff)
downloadmusl-4f3d346bffdf9ed2b1803653643dc31242490944.tar.gz
musl-4f3d346bffdf9ed2b1803653643dc31242490944.tar.xz
musl-4f3d346bffdf9ed2b1803653643dc31242490944.zip
math: fix fmaf not to depend on FE_TOWARDZERO
Diffstat (limited to 'src')
-rw-r--r--src/math/fmaf.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/src/math/fmaf.c b/src/math/fmaf.c
index 80f5cd8a..7c65acf1 100644
--- a/src/math/fmaf.c
+++ b/src/math/fmaf.c
@@ -77,17 +77,16 @@ float fmaf(float x, float y, float z)
* If result is inexact, and exactly halfway between two float values,
* we need to adjust the low-order bit in the direction of the error.
*/
-#ifdef FE_TOWARDZERO
- fesetround(FE_TOWARDZERO);
-#endif
- volatile double vxy = xy; /* XXX work around gcc CSE bug */
- double adjusted_result = vxy + z;
- fesetround(FE_TONEAREST);
- if (result == adjusted_result) {
- u.f = adjusted_result;
+ double err;
+ int neg = u.i >> 63;
+ if (neg == (z > xy))
+ err = xy - result + z;
+ else
+ err = z - result + xy;
+ if (neg == (err < 0))
u.i++;
- adjusted_result = u.f;
- }
- z = adjusted_result;
+ else
+ u.i--;
+ z = u.f;
return z;
}