blob: e2e66c1f7bc1af5d742fc0f2e32455eec93891ca [file]
// Copyright 2011 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.
#include "src/numbers/ieee754.h"
#include <cmath>
#include "src/base/ieee754.h"
#include "src/flags/flags.h"
namespace v8::internal::math {
double pow(double x, double y) {
if (v8_flags.use_std_math_pow) {
if (std::isnan(y)) {
// 1. If exponent is NaN, return NaN.
return std::numeric_limits<double>::quiet_NaN();
}
if (std::isinf(y) && (x == 1 || x == -1)) {
// 9. If exponent is +∞𝔽, then
// b. If abs(ℝ(base)) = 1, return NaN.
// and
// 10. If exponent is -∞𝔽, then
// b. If abs(ℝ(base)) = 1, return NaN.
return std::numeric_limits<double>::quiet_NaN();
}
if (std::isnan(x)) {
// std::pow distinguishes between quiet and signaling NaN; JS doesn't.
x = std::numeric_limits<double>::quiet_NaN();
}
// The following special cases just exist to match the optimizing compilers'
// behavior, which avoid calls to `pow` in those cases.
if (y == 2) {
// x ** 2 ==> x * x
return x * x;
} else if (y == 0.5) {
// x ** 0.5 ==> sqrt(x), except if x is -Infinity
if (std::isinf(x)) {
return std::numeric_limits<double>::infinity();
} else {
// Note the +0 so that we get +0 for -0**0.5 rather than -0.
return std::sqrt(x + 0);
}
}
return std::pow(x, y);
}
return base::ieee754::legacy::pow(x, y);
}
} // namespace v8::internal::math