Commit 7877ddec authored by bmeurer's avatar bmeurer Committed by Commit bot

[builtins] Make sure the Math functions and constants agree.

While the EcmaScript specification doesn't define precise values for the
Math constants or the Math functions, we should at least ensure that the
values of the constants and the functions agree, i.e. Math.E should be
exactly the same value as Math.exp(1).

Also make sure that Math.exp(1) returns the expected value; we should
revisit the fdlibm algorithm and figure out why it's wrong in the last
bit.

CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_chromium_rel_ng;tryserver.blink:linux_blink_rel
BUG=chromium:626111,v8:3266,v8:3468,v8:3493,v8:5086,v8:5108
R=yangguo@chromium.org

Review-Url: https://codereview.chromium.org/2079233005
Cr-Commit-Position: refs/heads/master@{#37128}
parent 42880af7
...@@ -1250,7 +1250,8 @@ double exp(double x) { ...@@ -1250,7 +1250,8 @@ double exp(double x) {
P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
E = 2.718281828459045; /* 0x4005bf0a, 0x8b145769 */
static volatile double static volatile double
huge = 1.0e+300, huge = 1.0e+300,
...@@ -1282,6 +1283,11 @@ double exp(double x) { ...@@ -1282,6 +1283,11 @@ double exp(double x) {
/* argument reduction */ /* argument reduction */
if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
/* TODO(rtoy): We special case exp(1) here to return the correct
* value of E, as the computation below would get the last bit
* wrong. We should probably fix the algorithm instead.
*/
if (x == 1.0) return E;
hi = x - ln2HI[xsb]; hi = x - ln2HI[xsb];
lo = ln2LO[xsb]; lo = ln2LO[xsb];
k = 1 - xsb - xsb; k = 1 - xsb - xsb;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "src/accessors.h" #include "src/accessors.h"
#include "src/api-natives.h" #include "src/api-natives.h"
#include "src/base/ieee754.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
#include "src/extensions/externalize-string-extension.h" #include "src/extensions/externalize-string-extension.h"
#include "src/extensions/free-buffer-extension.h" #include "src/extensions/free-buffer-extension.h"
...@@ -1703,6 +1704,28 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, ...@@ -1703,6 +1704,28 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
native_context()->set_math_sqrt(*math_sqrt); native_context()->set_math_sqrt(*math_sqrt);
SimpleInstallFunction(math, "tan", Builtins::kMathTan, 1, true); SimpleInstallFunction(math, "tan", Builtins::kMathTan, 1, true);
SimpleInstallFunction(math, "trunc", Builtins::kMathTrunc, 1, true); SimpleInstallFunction(math, "trunc", Builtins::kMathTrunc, 1, true);
// Install math constants.
double const kE = base::ieee754::exp(1.0);
JSObject::AddProperty(
math, factory->NewStringFromAsciiChecked("E"), factory->NewNumber(kE),
static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
JSObject::AddProperty(
math, factory->NewStringFromAsciiChecked("LN10"),
factory->NewNumber(base::ieee754::log(10.0)),
static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
JSObject::AddProperty(
math, factory->NewStringFromAsciiChecked("LN2"),
factory->NewNumber(base::ieee754::log(2.0)),
static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
JSObject::AddProperty(
math, factory->NewStringFromAsciiChecked("LOG10E"),
factory->NewNumber(base::ieee754::log10(kE)),
static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
JSObject::AddProperty(
math, factory->NewStringFromAsciiChecked("LOG2E"),
factory->NewNumber(base::ieee754::log2(kE)),
static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
} }
{ // -- A r r a y B u f f e r { // -- A r r a y B u f f e r
......
...@@ -127,15 +127,6 @@ function MathHypot(x, y) { // Function length is 2. ...@@ -127,15 +127,6 @@ function MathHypot(x, y) { // Function length is 2.
// Set up math constants. // Set up math constants.
utils.InstallConstants(GlobalMath, [ utils.InstallConstants(GlobalMath, [
// ECMA-262, section 15.8.1.1.
"E", 2.7182818284590452354,
// ECMA-262, section 15.8.1.2.
"LN10", 2.302585092994046,
// ECMA-262, section 15.8.1.3.
"LN2", 0.6931471805599453,
// ECMA-262, section 15.8.1.4.
"LOG2E", 1.4426950408889634,
"LOG10E", 0.4342944819032518,
"PI", 3.1415926535897932, "PI", 3.1415926535897932,
"SQRT1_2", 0.7071067811865476, "SQRT1_2", 0.7071067811865476,
"SQRT2", 1.4142135623730951 "SQRT2", 1.4142135623730951
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
assertEquals(Math.E, Math.exp(1));
assertEquals(Math.LN10, Math.log(10));
assertEquals(Math.LN2, Math.log(2));
assertEquals(Math.LOG10E, Math.log10(Math.E));
assertEquals(Math.LOG2E, Math.log2(Math.E));
assertEquals(Math.SQRT1_2, Math.sqrt(0.5));
assertEquals(Math.SQRT2, Math.sqrt(2));
...@@ -131,7 +131,7 @@ TEST(Ieee754, Exp) { ...@@ -131,7 +131,7 @@ TEST(Ieee754, Exp) {
EXPECT_EQ(1.0, exp(2.2250738585072014e-308)); EXPECT_EQ(1.0, exp(2.2250738585072014e-308));
EXPECT_GE(exp(1.0), exp(0.9999999999999999)); EXPECT_GE(exp(1.0), exp(0.9999999999999999));
EXPECT_LE(exp(1.0), exp(1.0000000000000002)); EXPECT_LE(exp(1.0), exp(1.0000000000000002));
EXPECT_EQ(2.7182818284590455, exp(1.0)); EXPECT_EQ(2.718281828459045, exp(1.0));
EXPECT_EQ(7.38905609893065e0, exp(2.0)); EXPECT_EQ(7.38905609893065e0, exp(2.0));
EXPECT_EQ(1.7976931348622732e308, exp(7.09782712893383973096e+02)); EXPECT_EQ(1.7976931348622732e308, exp(7.09782712893383973096e+02));
EXPECT_EQ(2.6881171418161356e+43, exp(100.0)); EXPECT_EQ(2.6881171418161356e+43, exp(100.0));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment