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,
// 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<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),
BigInt);
}
......
......@@ -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);
......
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