about summary refs log tree commit diff
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;
 }