Implement log10 via fdlibm port.

R=rtoy@chromium.org
BUG=v8:3579
LOG=N

Review URL: https://codereview.chromium.org/739913003

Cr-Commit-Position: refs/heads/master@{#25433}
This commit is contained in:
yangguo 2014-11-20 01:37:18 -08:00 committed by Commit bot
parent b3acdf5347
commit 529ff0cfbf
5 changed files with 126 additions and 63 deletions

View File

@ -227,12 +227,6 @@ function MathAtanh(x) {
return 0.5 * MathLog((1 + x) / (1 - x));
}
// ES6 draft 09-27-13, section 20.2.2.21.
function MathLog10(x) {
return MathLog(x) * 0.434294481903251828; // log10(x) = log(x)/log(10).
}
// ES6 draft 09-27-13, section 20.2.2.22.
function MathLog2(x) {
return MathLog(x) * 1.442695040888963407; // log2(x) = log(x)/log(2).
@ -369,7 +363,7 @@ function SetUpMath() {
"asinh", MathAsinh,
"acosh", MathAcosh,
"atanh", MathAtanh,
"log10", MathLog10,
"log10", MathLog10, // implemented by third_party/fdlibm
"log2", MathLog2,
"hypot", MathHypot,
"fround", MathFroundJS,

View File

@ -27,59 +27,62 @@ inline double scalbn(double x, int y) { return _scalb(x, y); }
#endif // _MSC_VER
const double MathConstants::constants[] = {
6.36619772367581382433e-01, // invpio2 0
1.57079632673412561417e+00, // pio2_1 1
6.07710050650619224932e-11, // pio2_1t 2
6.07710050630396597660e-11, // pio2_2 3
2.02226624879595063154e-21, // pio2_2t 4
2.02226624871116645580e-21, // pio2_3 5
8.47842766036889956997e-32, // pio2_3t 6
-1.66666666666666324348e-01, // S1 7 coefficients for sin
8.33333333332248946124e-03, // 8
-1.98412698298579493134e-04, // 9
2.75573137070700676789e-06, // 10
-2.50507602534068634195e-08, // 11
1.58969099521155010221e-10, // S6 12
4.16666666666666019037e-02, // C1 13 coefficients for cos
-1.38888888888741095749e-03, // 14
2.48015872894767294178e-05, // 15
-2.75573143513906633035e-07, // 16
2.08757232129817482790e-09, // 17
-1.13596475577881948265e-11, // C6 18
3.33333333333334091986e-01, // T0 19 coefficients for tan
1.33333333333201242699e-01, // 20
5.39682539762260521377e-02, // 21
2.18694882948595424599e-02, // 22
8.86323982359930005737e-03, // 23
3.59207910759131235356e-03, // 24
1.45620945432529025516e-03, // 25
5.88041240820264096874e-04, // 26
2.46463134818469906812e-04, // 27
7.81794442939557092300e-05, // 28
7.14072491382608190305e-05, // 29
-1.85586374855275456654e-05, // 30
2.59073051863633712884e-05, // T12 31
7.85398163397448278999e-01, // pio4 32
3.06161699786838301793e-17, // pio4lo 33
6.93147180369123816490e-01, // ln2_hi 34
1.90821492927058770002e-10, // ln2_lo 35
1.80143985094819840000e+16, // 2^54 36
6.666666666666666666e-01, // 2/3 37
6.666666666666735130e-01, // LP1 38 coefficients for log1p
3.999999999940941908e-01, // 39
2.857142874366239149e-01, // 40
2.222219843214978396e-01, // 41
1.818357216161805012e-01, // 42
1.531383769920937332e-01, // 43
1.479819860511658591e-01, // LP7 44
7.09782712893383973096e+02, // 45 overflow threshold for expm1
1.44269504088896338700e+00, // 1/ln2 46
-3.33333333333331316428e-02, // Q1 47 coefficients for expm1
1.58730158725481460165e-03, // 48
-7.93650757867487942473e-05, // 49
4.00821782732936239552e-06, // 50
-2.01099218183624371326e-07, // Q5 51
710.4758600739439 // 52 overflow threshold sinh, cosh
6.36619772367581382433e-01, // invpio2 0
1.57079632673412561417e+00, // pio2_1 1
6.07710050650619224932e-11, // pio2_1t 2
6.07710050630396597660e-11, // pio2_2 3
2.02226624879595063154e-21, // pio2_2t 4
2.02226624871116645580e-21, // pio2_3 5
8.47842766036889956997e-32, // pio2_3t 6
-1.66666666666666324348e-01, // S1 7 coefficients for sin
8.33333333332248946124e-03, // 8
-1.98412698298579493134e-04, // 9
2.75573137070700676789e-06, // 10
-2.50507602534068634195e-08, // 11
1.58969099521155010221e-10, // S6 12
4.16666666666666019037e-02, // C1 13 coefficients for cos
-1.38888888888741095749e-03, // 14
2.48015872894767294178e-05, // 15
-2.75573143513906633035e-07, // 16
2.08757232129817482790e-09, // 17
-1.13596475577881948265e-11, // C6 18
3.33333333333334091986e-01, // T0 19 coefficients for tan
1.33333333333201242699e-01, // 20
5.39682539762260521377e-02, // 21
2.18694882948595424599e-02, // 22
8.86323982359930005737e-03, // 23
3.59207910759131235356e-03, // 24
1.45620945432529025516e-03, // 25
5.88041240820264096874e-04, // 26
2.46463134818469906812e-04, // 27
7.81794442939557092300e-05, // 28
7.14072491382608190305e-05, // 29
-1.85586374855275456654e-05, // 30
2.59073051863633712884e-05, // T12 31
7.85398163397448278999e-01, // pio4 32
3.06161699786838301793e-17, // pio4lo 33
6.93147180369123816490e-01, // ln2_hi 34
1.90821492927058770002e-10, // ln2_lo 35
1.80143985094819840000e+16, // 2^54 36
6.666666666666666666e-01, // 2/3 37
6.666666666666735130e-01, // LP1 38 coefficients for log1p
3.999999999940941908e-01, // 39
2.857142874366239149e-01, // 40
2.222219843214978396e-01, // 41
1.818357216161805012e-01, // 42
1.531383769920937332e-01, // 43
1.479819860511658591e-01, // LP7 44
7.09782712893383973096e+02, // 45 overflow threshold for expm1
1.44269504088896338700e+00, // 1/ln2 46
-3.33333333333331316428e-02, // Q1 47 coefficients for expm1
1.58730158725481460165e-03, // 48
-7.93650757867487942473e-05, // 49
4.00821782732936239552e-06, // 50
-2.01099218183624371326e-07, // Q5 51
710.4758600739439, // 52 overflow threshold sinh, cosh
4.34294481903251816668e-01, // ivln10 53 coefficients for log10
3.01029995663611771306e-01, // log10_2hi 54
3.69423907715893078616e-13 // log10_2lo 55
};

View File

@ -23,7 +23,7 @@ int rempio2(double x, double* y);
// Constants to be exposed to builtins via Float64Array.
struct MathConstants {
static const double constants[53];
static const double constants[56];
};
}
} // namespace v8::internal

View File

@ -812,3 +812,66 @@ function MathCosh(x) {
// |x| > overflowthreshold.
return INFINITY;
}
// ES6 draft 09-27-13, section 20.2.2.21.
// Return the base 10 logarithm of x
//
// Method :
// Let log10_2hi = leading 40 bits of log10(2) and
// log10_2lo = log10(2) - log10_2hi,
// ivln10 = 1/log(10) rounded.
// Then
// n = ilogb(x),
// if(n<0) n = n+1;
// x = scalbn(x,-n);
// log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))
//
// Note 1:
// To guarantee log10(10**n)=n, where 10**n is normal, the rounding
// mode must set to Round-to-Nearest.
// Note 2:
// [1/log(10)] rounded to 53 bits has error .198 ulps;
// log10 is monotonic at all binary break points.
//
// Special cases:
// log10(x) is NaN if x < 0;
// log10(+INF) is +INF; log10(0) is -INF;
// log10(NaN) is that NaN;
// log10(10**N) = N for N=0,1,...,22.
//
const IVLN10 = kMath[53];
const LOG10_2HI = kMath[54];
const LOG10_2LO = kMath[55];
function MathLog10(x) {
x = x * 1; // Convert to number.
var hx = %_DoubleHi(x);
var lx = %_DoubleLo(x);
var k = 0;
if (hx < 0x00100000) {
// x < 2^-1022
// log10(+/- 0) = -Infinity.
if (((hx & 0x7fffffff) | lx) === 0) return -INFINITY;
// log10 of negative number is NaN.
if (hx < 0) return NAN;
// Subnormal number. Scale up x.
k -= 54;
x *= TWO54;
hx = %_DoubleHi(x);
lx = %_DoubleLo(x);
}
// Infinity or NaN.
if (hx >= 0x7ff00000) return x;
k += (hx >> 20) - 1023;
i = (k & 0x80000000) >> 31;
hx = (hx & 0x000fffff) | ((0x3ff - i) << 20);
y = k + i;
x = %_ConstructDouble(hx, lx);
z = y * LOG10_2LO + IVLN10 * MathLog(x);
return z + y * LOG10_2HI;
}

View File

@ -39,7 +39,10 @@
assertEquals("Infinity", String(fun(Infinity)));
});
for (var i = -300; i < 300; i += 0.7) {
assertEqualsDelta(i, Math.log10(Math.pow(10, i)), 1E-13);
for (var i = -310; i <= 308; i += 0.5) {
assertEquals(i, Math.log10(Math.pow(10, i)));
assertEqualsDelta(i, Math.log2(Math.pow(2, i)), 1E-13);
}
// Test denormals.
assertEquals(-307.77759430519706, Math.log10(1.5 * Math.pow(2, -1023)));