1
0
mirror of https://github.com/MikeMcl/decimal.js.git synced 2024-10-27 20:34:12 +00:00

#128 Add tinyPow to workaround V8 Math.pow change

This commit is contained in:
Michael Mclaughlin 2019-05-08 16:16:42 +01:00
parent fe487dc39e
commit f468de8e79
2 changed files with 30 additions and 18 deletions

View File

@ -317,7 +317,7 @@
external = false;
// Initial estimate.
s = x.s * Math.pow(x.s * x, 1 / 3);
s = x.s * mathpow(x.s * x, 1 / 3);
// Math.cbrt underflow/overflow?
// Pass x to Math.pow as integer, then adjust the exponent of the result.
@ -327,7 +327,7 @@
// Adjust n exponent so it is a multiple of 3 away from x exponent.
if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00');
s = Math.pow(n, 1 / 3);
s = mathpow(n, 1 / 3);
// Rarely, e may be one less than the result exponent value.
e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2));
@ -546,7 +546,7 @@
// TODO? Estimation reused from cosine() and may not be optimal here.
if (len < 32) {
k = Math.ceil(len / 3);
n = Math.pow(4, -k).toString();
n = (1 / tinyPow(4, k)).toString();
} else {
k = 16;
n = '2.3283064365386962890625e-10';
@ -626,8 +626,7 @@
k = 1.4 * Math.sqrt(len);
k = k > 16 ? 16 : k | 0;
x = x.times(Math.pow(5, -k));
x = x.times(1 / tinyPow(5, k));
x = taylorSeries(Ctor, 2, x, x, true);
// Reverse argument reduction
@ -2638,7 +2637,7 @@
// Estimate the optimum number of times to use the argument reduction.
if (len < 32) {
k = Math.ceil(len / 3);
y = Math.pow(4, -k).toString();
y = (1 / tinyPow(4, k)).toString();
} else {
k = 16;
y = '2.3283064365386962890625e-10';
@ -3649,7 +3648,7 @@
if (isFloat) x = divide(x, divisor, len * 4);
// Multiply by the binary exponent part if present.
if (p) x = x.times(Math.abs(p) < 54 ? Math.pow(2, p) : Decimal.pow(2, p));
if (p) x = x.times(Math.abs(p) < 54 ? mathpow(2, p) : Decimal.pow(2, p));
external = true;
return x;
@ -3675,8 +3674,7 @@
k = 1.4 * Math.sqrt(len);
k = k > 16 ? 16 : k | 0;
// Max k before Math.pow precision loss is 22
x = x.times(Math.pow(5, -k));
x = x.times(1 / tinyPow(5, k));
x = taylorSeries(Ctor, 2, x, x);
// Reverse argument reduction
@ -3729,6 +3727,14 @@
}
// Exponent e must be positive and non-zero.
function tinyPow(b, e) {
var n = b;
while (--e) n *= b;
return n;
}
// Return the absolute value of `x` reduced to less than or equal to half pi.
function toLessThanHalfPi(Ctor, x) {
var t,

View File

@ -313,7 +313,7 @@ P.cubeRoot = P.cbrt = function () {
external = false;
// Initial estimate.
s = x.s * Math.pow(x.s * x, 1 / 3);
s = x.s * mathpow(x.s * x, 1 / 3);
// Math.cbrt underflow/overflow?
// Pass x to Math.pow as integer, then adjust the exponent of the result.
@ -323,7 +323,7 @@ P.cubeRoot = P.cbrt = function () {
// Adjust n exponent so it is a multiple of 3 away from x exponent.
if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00');
s = Math.pow(n, 1 / 3);
s = mathpow(n, 1 / 3);
// Rarely, e may be one less than the result exponent value.
e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2));
@ -542,7 +542,7 @@ P.hyperbolicCosine = P.cosh = function () {
// TODO? Estimation reused from cosine() and may not be optimal here.
if (len < 32) {
k = Math.ceil(len / 3);
n = Math.pow(4, -k).toString();
n = (1 / tinyPow(4, k)).toString();
} else {
k = 16;
n = '2.3283064365386962890625e-10';
@ -622,8 +622,7 @@ P.hyperbolicSine = P.sinh = function () {
k = 1.4 * Math.sqrt(len);
k = k > 16 ? 16 : k | 0;
x = x.times(Math.pow(5, -k));
x = x.times(1 / tinyPow(5, k));
x = taylorSeries(Ctor, 2, x, x, true);
// Reverse argument reduction
@ -2634,7 +2633,7 @@ function cosine(Ctor, x) {
// Estimate the optimum number of times to use the argument reduction.
if (len < 32) {
k = Math.ceil(len / 3);
y = Math.pow(4, -k).toString();
y = (1 / tinyPow(4, k)).toString();
} else {
k = 16;
y = '2.3283064365386962890625e-10';
@ -3645,7 +3644,7 @@ function parseOther(x, str) {
if (isFloat) x = divide(x, divisor, len * 4);
// Multiply by the binary exponent part if present.
if (p) x = x.times(Math.abs(p) < 54 ? Math.pow(2, p) : Decimal.pow(2, p));
if (p) x = x.times(Math.abs(p) < 54 ? mathpow(2, p) : Decimal.pow(2, p));
external = true;
return x;
@ -3671,8 +3670,7 @@ function sine(Ctor, x) {
k = 1.4 * Math.sqrt(len);
k = k > 16 ? 16 : k | 0;
// Max k before Math.pow precision loss is 22
x = x.times(Math.pow(5, -k));
x = x.times(1 / tinyPow(5, k));
x = taylorSeries(Ctor, 2, x, x);
// Reverse argument reduction
@ -3725,6 +3723,14 @@ function taylorSeries(Ctor, n, x, y, isHyperbolic) {
}
// Exponent e must be positive and non-zero.
function tinyPow(b, e) {
var n = b;
while (--e) n *= b;
return n;
}
// Return the absolute value of `x` reduced to less than or equal to half pi.
function toLessThanHalfPi(Ctor, x) {
var t,