diff options
author | Timo Teräs <timo.teras@iki.fi> | 2017-06-01 13:29:51 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2017-06-01 13:31:29 +0300 |
commit | f6baa2aad98a418cd21b857f825e772a987b7c93 (patch) | |
tree | 510f68566eabbb6c8960020099b454ee5819bd18 /main/musl/0033-fix-scalbn-when-result-is-in-the-subnormal-range.patch | |
parent | acf34d0e48d8c8999406c748bfcf68c1ba61ddae (diff) | |
download | aports-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.patch | 89 |
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 + |