Harmony: implement Math.cbrt in Javascript.
R=jarin@chromium.org Review URL: https://codereview.chromium.org/183743018 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19742 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
2c74163f59
commit
4826aa7af2
@ -175,10 +175,29 @@ function MathClz32(x) {
|
||||
|
||||
|
||||
// ES6 draft 09-27-13, section 20.2.2.9.
|
||||
// Cube root approximation, refer to: http://metamerist.com/cbrt/cbrt.htm
|
||||
// Using initial approximation adapted from Kahan's cbrt and 4 iterations
|
||||
// of Newton's method.
|
||||
function MathCbrt(x) {
|
||||
return %Math_cbrt(TO_NUMBER_INLINE(x));
|
||||
if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
|
||||
if (x == 0 || !NUMBER_IS_FINITE(x)) return x;
|
||||
return x >= 0 ? CubeRoot(x) : -CubeRoot(-x);
|
||||
}
|
||||
|
||||
macro NEWTON_ITERATION_CBRT(x, approx)
|
||||
(1.0 / 3.0) * (x / (approx * approx) + 2 * approx);
|
||||
endmacro
|
||||
|
||||
function CubeRoot(x) {
|
||||
var approx_hi = MathFloor(%_DoubleHi(x) / 3) + 0x2A9F7893;
|
||||
var approx = %_ConstructDouble(approx_hi, 0);
|
||||
approx = NEWTON_ITERATION_CBRT(x, approx);
|
||||
approx = NEWTON_ITERATION_CBRT(x, approx);
|
||||
approx = NEWTON_ITERATION_CBRT(x, approx);
|
||||
return NEWTON_ITERATION_CBRT(x, approx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ES6 draft 09-27-13, section 20.2.2.14.
|
||||
// Use Taylor series to approximate.
|
||||
|
@ -7694,36 +7694,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ConstructDouble) {
|
||||
}
|
||||
|
||||
|
||||
// Cube root approximation, refer to: http://metamerist.com/cbrt/cbrt.htm
|
||||
// Using initial approximation adapted from Kahan's cbrt and 4 iterations
|
||||
// of Newton's method.
|
||||
inline double CubeRootNewtonIteration(double approx, double x) {
|
||||
return (1.0 / 3.0) * (x / (approx * approx) + 2 * approx);
|
||||
}
|
||||
|
||||
|
||||
inline double CubeRoot(double x) {
|
||||
static const uint64_t magic = V8_2PART_UINT64_C(0x2A9F7893, 00000000);
|
||||
uint64_t xhigh = double_to_uint64(x);
|
||||
double approx = uint64_to_double(xhigh / 3 + magic);
|
||||
|
||||
approx = CubeRootNewtonIteration(approx, x);
|
||||
approx = CubeRootNewtonIteration(approx, x);
|
||||
approx = CubeRootNewtonIteration(approx, x);
|
||||
return CubeRootNewtonIteration(approx, x);
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cbrt) {
|
||||
SealHandleScope shs(isolate);
|
||||
ASSERT(args.length() == 1);
|
||||
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
|
||||
if (x == 0 || std::isinf(x)) return args[0];
|
||||
double result = (x > 0) ? CubeRoot(x) : -CubeRoot(-x);
|
||||
return isolate->heap()->AllocateHeapNumber(result);
|
||||
}
|
||||
|
||||
|
||||
static const double kPiDividedBy4 = 0.78539816339744830962;
|
||||
|
||||
|
||||
|
@ -175,7 +175,6 @@ namespace internal {
|
||||
F(Math_asin, 1, 1) \
|
||||
F(Math_atan, 1, 1) \
|
||||
F(Math_log, 1, 1) \
|
||||
F(Math_cbrt, 1, 1) \
|
||||
F(Math_sqrt, 1, 1) \
|
||||
F(Math_exp, 1, 1) \
|
||||
F(Math_floor, 1, 1) \
|
||||
|
Loading…
Reference in New Issue
Block a user