aboutsummaryrefslogtreecommitdiffstats
path: root/main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2017-06-01 13:29:51 +0300
committerTimo Teräs <timo.teras@iki.fi>2017-06-01 13:31:29 +0300
commitf6baa2aad98a418cd21b857f825e772a987b7c93 (patch)
tree510f68566eabbb6c8960020099b454ee5819bd18 /main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch
parentacf34d0e48d8c8999406c748bfcf68c1ba61ddae (diff)
downloadaports-f6baa2aad98a418cd21b857f825e772a987b7c93.tar.bz2
aports-f6baa2aad98a418cd21b857f825e772a987b7c93.tar.xz
main/musl: cherry-pick upstream fixes, add strftime gnu extensions
ref #5907
Diffstat (limited to 'main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch')
-rw-r--r--main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch89
1 files changed, 89 insertions, 0 deletions
diff --git a/main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch b/main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch
new file mode 100644
index 0000000000..a29a18efe5
--- /dev/null
+++ b/main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch
@@ -0,0 +1,89 @@
+From 8c44a060243f04283ca68dad199aab90336141db Mon Sep 17 00:00:00 2001
+From: Szabolcs Nagy <nsz@port70.net>
+Date: Mon, 3 Apr 2017 02:38:13 +0200
+Subject: [PATCH] fix scalbn when result is in the subnormal range
+
+in nearest rounding mode scalbn could introduce double rounding error
+when an intermediate value and the final result were both in the
+subnormal range e.g.
+
+ scalbn(0x1.7ffffffffffffp-1, -1073)
+
+returned 0x1p-1073 instead of 0x1p-1074, because the intermediate
+computation got rounded to 0x1.8p-1023.
+
+with the fix an intermediate value can only be in the subnormal range
+if the final result is 0 which is correct even after double rounding.
+(there still can be two roundings so signals may be raised twice, but
+that's only observable with trapping exceptions which is not supported.)
+---
+ src/math/scalbn.c | 10 ++++++----
+ src/math/scalbnf.c | 8 ++++----
+ src/math/scalbnl.c | 8 ++++----
+ 3 files changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/src/math/scalbn.c b/src/math/scalbn.c
+index 530e07c7..182f5610 100644
+--- a/src/math/scalbn.c
++++ b/src/math/scalbn.c
+@@ -16,11 +16,13 @@ double scalbn(double x, int n)
+ n = 1023;
+ }
+ } else if (n < -1022) {
+- y *= 0x1p-1022;
+- n += 1022;
++ /* make sure final n < -53 to avoid double
++ rounding in the subnormal range */
++ y *= 0x1p-1022 * 0x1p53;
++ n += 1022 - 53;
+ if (n < -1022) {
+- y *= 0x1p-1022;
+- n += 1022;
++ y *= 0x1p-1022 * 0x1p53;
++ n += 1022 - 53;
+ if (n < -1022)
+ n = -1022;
+ }
+diff --git a/src/math/scalbnf.c b/src/math/scalbnf.c
+index 0b62c3c7..a5ad208b 100644
+--- a/src/math/scalbnf.c
++++ b/src/math/scalbnf.c
+@@ -16,11 +16,11 @@ float scalbnf(float x, int n)
+ n = 127;
+ }
+ } else if (n < -126) {
+- y *= 0x1p-126f;
+- n += 126;
++ y *= 0x1p-126f * 0x1p24f;
++ n += 126 - 24;
+ if (n < -126) {
+- y *= 0x1p-126f;
+- n += 126;
++ y *= 0x1p-126f * 0x1p24f;
++ n += 126 - 24;
+ if (n < -126)
+ n = -126;
+ }
+diff --git a/src/math/scalbnl.c b/src/math/scalbnl.c
+index 08a4c587..db44dab0 100644
+--- a/src/math/scalbnl.c
++++ b/src/math/scalbnl.c
+@@ -20,11 +20,11 @@ long double scalbnl(long double x, int n)
+ n = 16383;
+ }
+ } else if (n < -16382) {
+- x *= 0x1p-16382L;
+- n += 16382;
++ x *= 0x1p-16382L * 0x1p113L;
++ n += 16382 - 113;
+ if (n < -16382) {
+- x *= 0x1p-16382L;
+- n += 16382;
++ x *= 0x1p-16382L * 0x1p113L;
++ n += 16382 - 113;
+ if (n < -16382)
+ n = -16382;
+ }
+--
+2.13.0
+