diff --git a/src/objects/bigint.cc b/src/objects/bigint.cc index db00ab1bf1ff..ee21d52a5600 100644 --- a/src/objects/bigint.cc +++ b/src/objects/bigint.cc @@ -323,10 +323,18 @@ MaybeHandle BigInt::Exponentiate(Handle base, // 3. Return a BigInt representing the mathematical value of base raised // to the power exponent. if (base->is_zero()) return base; + if (base->length() == 1 && base->digit(0) == 1) { + // (-1) ** even_number == 1. + if (base->sign() && (exponent->digit(0) & 1) == 0) { + return UnaryMinus(base); + } + // (-1) ** odd_number == -1; 1 ** anything == 1. + return base; + } // For all bases >= 2, very large exponents would lead to unrepresentable // results. STATIC_ASSERT(kMaxLengthBits < std::numeric_limits::max()); - if (!(base->length() == 1 && base->digit(0) == 1) && exponent->length() > 1) { + if (exponent->length() > 1) { THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig), BigInt); } diff --git a/test/mjsunit/harmony/bigint/exp.js b/test/mjsunit/harmony/bigint/exp.js index 812173323982..54d5849373f5 100644 --- a/test/mjsunit/harmony/bigint/exp.js +++ b/test/mjsunit/harmony/bigint/exp.js @@ -9,6 +9,9 @@ assertEquals(-1n, (-1n) ** 1n); assertEquals(1n, (-1n) ** 2n); assertEquals(-1n, (-1n) ** 3n); assertEquals(1n, (-1n) ** 4n); +// Multi-digit exponents. +assertEquals(1n, (-1n) ** (2n ** 80n)); +assertEquals(-1n, (-1n) ** ((2n ** 80n) + 1n)); assertEquals(1n, 0n ** 0n); assertEquals(0n, 0n ** 1n);