[bigint] Implement BigInt.asIntN.
Bug: v8:6791 Change-Id: I10f8c6c88c534ee1e3c893176b6563af0c9f99d3 Reviewed-on: https://chromium-review.googlesource.com/753904 Commit-Queue: Georg Neis <neis@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#49180}
This commit is contained in:
parent
6e1c57eaa9
commit
55062ced0b
@ -86,11 +86,16 @@ BUILTIN(BigIntAsIntN) {
|
||||
Handle<Object> bits_obj = args.atOrUndefined(isolate, 1);
|
||||
Handle<Object> bigint_obj = args.atOrUndefined(isolate, 2);
|
||||
|
||||
// TODO(jkummerow): Implement.
|
||||
USE(bits_obj);
|
||||
USE(bigint_obj);
|
||||
Handle<Object> bits;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, bits,
|
||||
Object::ToIndex(isolate, bits_obj, MessageTemplate::kInvalidIndex));
|
||||
|
||||
UNIMPLEMENTED();
|
||||
Handle<BigInt> bigint;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, bigint,
|
||||
BigInt::FromObject(isolate, bigint_obj));
|
||||
|
||||
return *BigInt::AsIntN(bits->Number(), bigint);
|
||||
}
|
||||
|
||||
BUILTIN(BigIntPrototypeToLocaleString) {
|
||||
|
@ -1588,15 +1588,61 @@ MaybeHandle<String> BigInt::ToStringGeneric(Handle<BigInt> x, int radix) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Handle<BigInt> BigInt::AsIntN(uint64_t n, Handle<BigInt> x) {
|
||||
DCHECK_LE(n, kMaxSafeInteger);
|
||||
Isolate* isolate = x->GetIsolate();
|
||||
|
||||
Handle<BigInt> result = AbsoluteAsUintN(n, x);
|
||||
if (result->is_zero()) return result;
|
||||
DCHECK_NE(n, 0);
|
||||
DCHECK(!x->is_zero());
|
||||
|
||||
// Compare abs(result) against 2^(n-1).
|
||||
int comparison;
|
||||
{
|
||||
// 2^(n-1) needs n bits.
|
||||
uint64_t power_length = (n + kDigitBits - 1) / kDigitBits;
|
||||
if (static_cast<uint64_t>(result->length()) < power_length) {
|
||||
comparison = -1;
|
||||
} else {
|
||||
DCHECK_EQ(result->length(), power_length);
|
||||
DCHECK_LE(n, kMaxInt);
|
||||
// TODO(neis): Ideally we shouldn't allocate here at all.
|
||||
comparison = AbsoluteCompare(result, PowerOfTwo(isolate, n - 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (!x->sign()) {
|
||||
// x is positive. Note that result == x mod 2^n.
|
||||
if (comparison < 0) return result;
|
||||
// Return (x mod 2^n) - 2^n, which is -(2^n - x mod 2^n).
|
||||
return AbsoluteSub(PowerOfTwo(isolate, n), result, true);
|
||||
}
|
||||
|
||||
// x is negative. Note that abs(result) == -x mod 2^n.
|
||||
// We use the following facts:
|
||||
// a) (x mod 2^n) == 2^n - abs(result)
|
||||
// b) (x mod 2^n) >= 2^(n-1) iff
|
||||
// 2^n - abs(result) >= 2^(n-1) iff
|
||||
// 2^(n-1) >= abs(result) iff
|
||||
// comparison <= 0
|
||||
if (comparison <= 0) {
|
||||
// Return (x mod 2^n) - 2^n, which is -abs(result).
|
||||
return result->sign() ? result : UnaryMinus(result);
|
||||
}
|
||||
// Return x mod 2^n.
|
||||
return AbsoluteSub(PowerOfTwo(isolate, n), result, false);
|
||||
}
|
||||
|
||||
Handle<BigInt> BigInt::AsUintN(uint64_t n, Handle<BigInt> x) {
|
||||
DCHECK_LE(n, kMaxSafeInteger);
|
||||
Handle<BigInt> result = AbsoluteAsUintN(n, x);
|
||||
if (!x->sign()) return result;
|
||||
|
||||
// x is negative.
|
||||
// Note that result == -x % 2^n. We use the following facts:
|
||||
// If result == 0, then x % 2^n == 0.
|
||||
// If result != 0, then x % 2^n == 2^n - result.
|
||||
// x is negative. Note that abs(result) == -x mod 2^n.
|
||||
// We use the following facts:
|
||||
// a) If result == 0, then (x mod 2^n) == 0.
|
||||
// b) If result != 0, then (x mod 2^n) == 2^n - abs(result).
|
||||
if (result->is_zero()) return result;
|
||||
return AbsoluteSub(PowerOfTwo(x->GetIsolate(), n), result, false);
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ class V8_EXPORT_PRIVATE BigInt : public HeapObject {
|
||||
// Exposed for tests, do not call directly. Use CompareToNumber() instead.
|
||||
static ComparisonResult CompareToDouble(Handle<BigInt> x, double y);
|
||||
|
||||
static Handle<BigInt> AsIntN(uint64_t n, Handle<BigInt> x);
|
||||
static Handle<BigInt> AsUintN(uint64_t n, Handle<BigInt> x);
|
||||
|
||||
DECL_CAST(BigInt)
|
||||
|
@ -276,9 +276,146 @@ const six = BigInt(6);
|
||||
}
|
||||
}
|
||||
|
||||
// .asUintN
|
||||
// BigInt.asIntN
|
||||
{
|
||||
assertEquals(2, BigInt.asIntN.length);
|
||||
}{
|
||||
assertEquals(254n, BigInt.asIntN(10, 254n));
|
||||
assertEquals(255n, BigInt.asIntN(10, 255n));
|
||||
assertEquals(256n, BigInt.asIntN(10, 256n));
|
||||
assertEquals(257n, BigInt.asIntN(10, 257n));
|
||||
assertEquals(510n, BigInt.asIntN(10, 510n));
|
||||
assertEquals(511n, BigInt.asIntN(10, 511n));
|
||||
assertEquals(-512n, BigInt.asIntN(10, 512n));
|
||||
assertEquals(-511n, BigInt.asIntN(10, 513n));
|
||||
assertEquals(-2n, BigInt.asIntN(10, 1022n));
|
||||
assertEquals(-1n, BigInt.asIntN(10, 1023n));
|
||||
assertEquals(0n, BigInt.asIntN(10, 1024n));
|
||||
assertEquals(1n, BigInt.asIntN(10, 1025n));
|
||||
}{
|
||||
assertEquals(-254n, BigInt.asIntN(10, -254n));
|
||||
assertEquals(-255n, BigInt.asIntN(10, -255n));
|
||||
assertEquals(-256n, BigInt.asIntN(10, -256n));
|
||||
assertEquals(-257n, BigInt.asIntN(10, -257n));
|
||||
assertEquals(-510n, BigInt.asIntN(10, -510n));
|
||||
assertEquals(-511n, BigInt.asIntN(10, -511n));
|
||||
assertEquals(-512n, BigInt.asIntN(10, -512n));
|
||||
assertEquals(511n, BigInt.asIntN(10, -513n));
|
||||
assertEquals(2n, BigInt.asIntN(10, -1022n));
|
||||
assertEquals(1n, BigInt.asIntN(10, -1023n));
|
||||
assertEquals(0n, BigInt.asIntN(10, -1024n));
|
||||
assertEquals(-1n, BigInt.asIntN(10, -1025n));
|
||||
}{
|
||||
assertEquals(0n, BigInt.asIntN(0, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(1, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(16, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(31, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(32, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(33, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(63, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(64, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(65, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(127, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(128, 0n));
|
||||
assertEquals(0n, BigInt.asIntN(129, 0n));
|
||||
}{
|
||||
assertEquals(0n, BigInt.asIntN(0, 42n));
|
||||
assertEquals(0n, BigInt.asIntN(1, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(16, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(31, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(32, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(33, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(63, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(64, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(65, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(127, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(128, 42n));
|
||||
assertEquals(42n, BigInt.asIntN(129, 42n));
|
||||
}{
|
||||
assertEquals(0n, BigInt.asIntN(0, -42n));
|
||||
assertEquals(0n, BigInt.asIntN(1, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(16, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(31, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(32, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(33, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(63, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(64, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(65, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(127, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(128, -42n));
|
||||
assertEquals(-42n, BigInt.asIntN(129, -42n));
|
||||
}{
|
||||
assertEquals(0n, BigInt.asIntN(0, 4294967295n));
|
||||
assertEquals(-1n, BigInt.asIntN(1, 4294967295n));
|
||||
assertEquals(-1n, BigInt.asIntN(16, 4294967295n));
|
||||
assertEquals(-1n, BigInt.asIntN(31, 4294967295n));
|
||||
assertEquals(-1n, BigInt.asIntN(32, 4294967295n));
|
||||
assertEquals(4294967295n, BigInt.asIntN(33, 4294967295n));
|
||||
assertEquals(4294967295n, BigInt.asIntN(63, 4294967295n));
|
||||
assertEquals(4294967295n, BigInt.asIntN(64, 4294967295n));
|
||||
assertEquals(4294967295n, BigInt.asIntN(65, 4294967295n));
|
||||
assertEquals(4294967295n, BigInt.asIntN(127, 4294967295n));
|
||||
assertEquals(4294967295n, BigInt.asIntN(128, 4294967295n));
|
||||
assertEquals(4294967295n, BigInt.asIntN(129, 4294967295n));
|
||||
}{
|
||||
assertEquals(0n, BigInt.asIntN(0, -4294967295n));
|
||||
assertEquals(-1n, BigInt.asIntN(1, -4294967295n));
|
||||
assertEquals(1n, BigInt.asIntN(16, -4294967295n));
|
||||
assertEquals(1n, BigInt.asIntN(31, -4294967295n));
|
||||
assertEquals(1n, BigInt.asIntN(32, -4294967295n));
|
||||
assertEquals(-4294967295n, BigInt.asIntN(33, -4294967295n));
|
||||
assertEquals(-4294967295n, BigInt.asIntN(63, -4294967295n));
|
||||
assertEquals(-4294967295n, BigInt.asIntN(64,-4294967295n));
|
||||
assertEquals(-4294967295n, BigInt.asIntN(65, -4294967295n));
|
||||
assertEquals(-4294967295n, BigInt.asIntN(127, -4294967295n));
|
||||
assertEquals(-4294967295n, BigInt.asIntN(128, -4294967295n));
|
||||
assertEquals(-4294967295n, BigInt.asIntN(129, -4294967295n));
|
||||
}{
|
||||
assertEquals(42n, BigInt.asIntN(2**32, 42n));
|
||||
assertEquals(4294967295n, BigInt.asIntN(2**32, 4294967295n));
|
||||
assertEquals(4294967296n, BigInt.asIntN(2**32, 4294967296n));
|
||||
assertEquals(4294967297n, BigInt.asIntN(2**32, 4294967297n));
|
||||
}{
|
||||
assertThrows(() => BigInt.asIntN(2n, 12n), TypeError);
|
||||
assertThrows(() => BigInt.asIntN(-1, 0n), RangeError);
|
||||
assertThrows(() => BigInt.asIntN(2**53, 0n), RangeError);
|
||||
assertEquals(0n, BigInt.asIntN({}, 12n));
|
||||
assertEquals(0n, BigInt.asIntN(2.9999, 12n));
|
||||
assertEquals(-4n, BigInt.asIntN(3.1234, 12n));
|
||||
}{
|
||||
assertThrows(() => BigInt.asIntN(3, 12), TypeError);
|
||||
assertEquals(-4n, BigInt.asIntN(3, "12"));
|
||||
}
|
||||
|
||||
// BigInt.asUintN
|
||||
{
|
||||
assertEquals(2, BigInt.asUintN.length);
|
||||
}{
|
||||
assertEquals(254n, BigInt.asUintN(10, 254n));
|
||||
assertEquals(255n, BigInt.asUintN(10, 255n));
|
||||
assertEquals(256n, BigInt.asUintN(10, 256n));
|
||||
assertEquals(257n, BigInt.asUintN(10, 257n));
|
||||
assertEquals(510n, BigInt.asUintN(10, 510n));
|
||||
assertEquals(511n, BigInt.asUintN(10, 511n));
|
||||
assertEquals(512n, BigInt.asUintN(10, 512n));
|
||||
assertEquals(513n, BigInt.asUintN(10, 513n));
|
||||
assertEquals(1022n, BigInt.asUintN(10, 1022n));
|
||||
assertEquals(1023n, BigInt.asUintN(10, 1023n));
|
||||
assertEquals(0n, BigInt.asUintN(10, 1024n));
|
||||
assertEquals(1n, BigInt.asUintN(10, 1025n));
|
||||
}{
|
||||
assertEquals(1024n - 254n, BigInt.asUintN(10, -254n));
|
||||
assertEquals(1024n - 255n, BigInt.asUintN(10, -255n));
|
||||
assertEquals(1024n - 256n, BigInt.asUintN(10, -256n));
|
||||
assertEquals(1024n - 257n, BigInt.asUintN(10, -257n));
|
||||
assertEquals(1024n - 510n, BigInt.asUintN(10, -510n));
|
||||
assertEquals(1024n - 511n, BigInt.asUintN(10, -511n));
|
||||
assertEquals(1024n - 512n, BigInt.asUintN(10, -512n));
|
||||
assertEquals(1024n - 513n, BigInt.asUintN(10, -513n));
|
||||
assertEquals(1024n - 1022n, BigInt.asUintN(10, -1022n));
|
||||
assertEquals(1024n - 1023n, BigInt.asUintN(10, -1023n));
|
||||
assertEquals(0n, BigInt.asUintN(10, -1024n));
|
||||
assertEquals(1023n, BigInt.asUintN(10, -1025n));
|
||||
}{
|
||||
assertEquals(0n, BigInt.asUintN(0, 0n));
|
||||
assertEquals(0n, BigInt.asUintN(1, 0n));
|
||||
|
Loading…
Reference in New Issue
Block a user