Commit 66f21389 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[bigint] Fix Exponentiate for 1 ** multi_digit

Bug: chromium:819026
Change-Id: I2c58d5e2892f683747966e00aa047153085ac121
Reviewed-on: https://chromium-review.googlesource.com/950472Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51776}
parent a7a7f299
...@@ -323,10 +323,18 @@ MaybeHandle<BigInt> BigInt::Exponentiate(Handle<BigInt> base, ...@@ -323,10 +323,18 @@ MaybeHandle<BigInt> BigInt::Exponentiate(Handle<BigInt> base,
// 3. Return a BigInt representing the mathematical value of base raised // 3. Return a BigInt representing the mathematical value of base raised
// to the power exponent. // to the power exponent.
if (base->is_zero()) return base; 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 // For all bases >= 2, very large exponents would lead to unrepresentable
// results. // results.
STATIC_ASSERT(kMaxLengthBits < std::numeric_limits<digit_t>::max()); STATIC_ASSERT(kMaxLengthBits < std::numeric_limits<digit_t>::max());
if (!(base->length() == 1 && base->digit(0) == 1) && exponent->length() > 1) { if (exponent->length() > 1) {
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig), THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig),
BigInt); BigInt);
} }
......
...@@ -9,6 +9,9 @@ assertEquals(-1n, (-1n) ** 1n); ...@@ -9,6 +9,9 @@ assertEquals(-1n, (-1n) ** 1n);
assertEquals(1n, (-1n) ** 2n); assertEquals(1n, (-1n) ** 2n);
assertEquals(-1n, (-1n) ** 3n); assertEquals(-1n, (-1n) ** 3n);
assertEquals(1n, (-1n) ** 4n); assertEquals(1n, (-1n) ** 4n);
// Multi-digit exponents.
assertEquals(1n, (-1n) ** (2n ** 80n));
assertEquals(-1n, (-1n) ** ((2n ** 80n) + 1n));
assertEquals(1n, 0n ** 0n); assertEquals(1n, 0n ** 0n);
assertEquals(0n, 0n ** 1n); assertEquals(0n, 0n ** 1n);
......
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