diff options
author | Szabolcs Nagy <nsz@port70.net> | 2021-07-05 22:37:22 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2021-07-06 00:29:57 -0400 |
commit | 4f3d346bffdf9ed2b1803653643dc31242490944 (patch) | |
tree | c89c3502fac36a715e2621aa1d0dc90344389bcd /src | |
parent | 937822abb6ac48880939be3c60e6b57bddf62cf6 (diff) | |
download | musl-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.c | 21 |
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; } |