From f6baa2aad98a418cd21b857f825e772a987b7c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Thu, 1 Jun 2017 13:29:51 +0300 Subject: main/musl: cherry-pick upstream fixes, add strftime gnu extensions ref #5907 --- ...lbn-when-result-is-in-the-subnormal-range.patch | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch (limited to 'main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch') 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 +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 + -- cgit v1.2.3