[bigint] Implement comparisons with Numbers/Strings
This patch provides "Abstract Comparison" functions on the BigInt class for comparing BigInts to Numbers and Strings. The functionality is not exposed to JavaScript yet. Bug: v8:6791 Change-Id: I835f290203a31f363970b1edb359e19af6dabc5d Reviewed-on: https://chromium-review.googlesource.com/722324 Commit-Queue: Georg Neis <neis@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#48718}
This commit is contained in:
parent
8c98e07c82
commit
94b8894392
@ -113,7 +113,8 @@ MaybeHandle<BigInt> StringToBigInt(Isolate* isolate, Handle<String> string,
|
||||
// 0x -> hex
|
||||
// 0o -> octal
|
||||
// 0b -> binary
|
||||
MaybeHandle<BigInt> StringToBigInt(Isolate* isolate, const char* string);
|
||||
V8_EXPORT_PRIVATE MaybeHandle<BigInt> StringToBigInt(Isolate* isolate,
|
||||
const char* string);
|
||||
|
||||
const int kDoubleToCStringMinBufferSize = 100;
|
||||
|
||||
|
@ -627,7 +627,7 @@ bool Object::StrictEquals(Object* that) {
|
||||
return String::cast(this)->Equals(String::cast(that));
|
||||
} else if (this->IsBigInt()) {
|
||||
if (!that->IsBigInt()) return false;
|
||||
return BigInt::Equal(BigInt::cast(this), BigInt::cast(that));
|
||||
return BigInt::EqualToBigInt(BigInt::cast(this), BigInt::cast(that));
|
||||
}
|
||||
return this == that;
|
||||
}
|
||||
@ -2437,7 +2437,7 @@ bool Object::SameValue(Object* other) {
|
||||
return String::cast(this)->Equals(String::cast(other));
|
||||
}
|
||||
if (IsBigInt() && other->IsBigInt()) {
|
||||
return BigInt::Equal(BigInt::cast(this), BigInt::cast(other));
|
||||
return BigInt::EqualToBigInt(BigInt::cast(this), BigInt::cast(other));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -2457,7 +2457,7 @@ bool Object::SameValueZero(Object* other) {
|
||||
return String::cast(this)->Equals(String::cast(other));
|
||||
}
|
||||
if (IsBigInt() && other->IsBigInt()) {
|
||||
return BigInt::Equal(BigInt::cast(this), BigInt::cast(other));
|
||||
return BigInt::EqualToBigInt(BigInt::cast(this), BigInt::cast(other));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "src/objects/bigint.h"
|
||||
|
||||
#include "src/double.h"
|
||||
#include "src/objects-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -165,15 +166,37 @@ MaybeHandle<BigInt> BigInt::UnsignedRightShift(Handle<BigInt> x,
|
||||
BigInt);
|
||||
}
|
||||
|
||||
bool BigInt::LessThan(Handle<BigInt> x, Handle<BigInt> y) {
|
||||
if (x->sign() == y->sign()) {
|
||||
int result = AbsoluteCompare(x, y);
|
||||
return x->sign() ? (result > 0) : (result < 0);
|
||||
}
|
||||
return x->sign();
|
||||
namespace {
|
||||
|
||||
// Produces comparison result for {left_negative} == sign(x) != sign(y).
|
||||
ComparisonResult UnequalSign(bool left_negative) {
|
||||
return left_negative ? ComparisonResult::kLessThan
|
||||
: ComparisonResult::kGreaterThan;
|
||||
}
|
||||
// Produces result for |x| > |y|, with {both_negative} == sign(x) == sign(y);
|
||||
ComparisonResult AbsoluteGreater(bool both_negative) {
|
||||
return both_negative ? ComparisonResult::kLessThan
|
||||
: ComparisonResult::kGreaterThan;
|
||||
}
|
||||
// Produces result for |x| < |y|, with {both_negative} == sign(x) == sign(y).
|
||||
ComparisonResult AbsoluteLess(bool both_negative) {
|
||||
return both_negative ? ComparisonResult::kGreaterThan
|
||||
: ComparisonResult::kLessThan;
|
||||
}
|
||||
|
||||
bool BigInt::Equal(BigInt* x, BigInt* y) {
|
||||
} // namespace
|
||||
|
||||
ComparisonResult BigInt::CompareToBigInt(Handle<BigInt> x, Handle<BigInt> y) {
|
||||
bool x_sign = x->sign();
|
||||
if (x_sign != y->sign()) return UnequalSign(x_sign);
|
||||
|
||||
int result = AbsoluteCompare(x, y);
|
||||
if (result > 0) return AbsoluteGreater(x_sign);
|
||||
if (result < 0) return AbsoluteLess(x_sign);
|
||||
return ComparisonResult::kEqual;
|
||||
}
|
||||
|
||||
bool BigInt::EqualToBigInt(BigInt* x, BigInt* y) {
|
||||
if (x->sign() != y->sign()) return false;
|
||||
if (x->length() != y->length()) return false;
|
||||
for (int i = 0; i < x->length(); i++) {
|
||||
@ -279,6 +302,173 @@ MaybeHandle<BigInt> BigInt::Decrement(Handle<BigInt> x) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool BigInt::EqualToString(Handle<BigInt> x, Handle<String> y) {
|
||||
Isolate* isolate = x->GetIsolate();
|
||||
// a. Let n be StringToBigInt(y).
|
||||
MaybeHandle<BigInt> maybe_n = StringToBigInt(isolate, y, 10);
|
||||
// b. If n is NaN, return false.
|
||||
Handle<BigInt> n;
|
||||
if (!maybe_n.ToHandle(&n)) {
|
||||
DCHECK(isolate->has_pending_exception());
|
||||
isolate->clear_pending_exception();
|
||||
return false;
|
||||
}
|
||||
// c. Return the result of x == n.
|
||||
return EqualToBigInt(*x, *n);
|
||||
}
|
||||
|
||||
bool BigInt::EqualToNumber(Handle<BigInt> x, Handle<Object> y) {
|
||||
DCHECK(y->IsNumber());
|
||||
// a. If x or y are any of NaN, +∞, or -∞, return false.
|
||||
// b. If the mathematical value of x is equal to the mathematical value of y,
|
||||
// return true, otherwise return false.
|
||||
if (y->IsSmi()) {
|
||||
int value = Smi::ToInt(*y);
|
||||
if (value == 0) return x->is_zero();
|
||||
// Any multi-digit BigInt is bigger than a Smi.
|
||||
STATIC_ASSERT(sizeof(digit_t) >= sizeof(value));
|
||||
return (x->length() == 1) && (x->sign() == (value < 0)) &&
|
||||
(x->digit(0) ==
|
||||
static_cast<digit_t>(std::abs(static_cast<int64_t>(value))));
|
||||
}
|
||||
DCHECK(y->IsHeapNumber());
|
||||
double value = Handle<HeapNumber>::cast(y)->value();
|
||||
return CompareToDouble(x, value) == ComparisonResult::kEqual;
|
||||
}
|
||||
|
||||
ComparisonResult BigInt::CompareToNumber(Handle<BigInt> x, Handle<Object> y) {
|
||||
DCHECK(y->IsNumber());
|
||||
if (y->IsSmi()) {
|
||||
bool x_sign = x->sign();
|
||||
int y_value = Smi::ToInt(*y);
|
||||
bool y_sign = (y_value < 0);
|
||||
if (x_sign != y_sign) return UnequalSign(x_sign);
|
||||
|
||||
if (x->is_zero()) {
|
||||
DCHECK(!y_sign);
|
||||
return y_value == 0 ? ComparisonResult::kEqual
|
||||
: ComparisonResult::kLessThan;
|
||||
}
|
||||
// Any multi-digit BigInt is bigger than a Smi.
|
||||
STATIC_ASSERT(sizeof(digit_t) >= sizeof(y_value));
|
||||
if (x->length() > 1) return AbsoluteGreater(x_sign);
|
||||
|
||||
digit_t abs_value = std::abs(static_cast<int64_t>(y_value));
|
||||
digit_t x_digit = x->digit(0);
|
||||
if (x_digit > abs_value) return AbsoluteGreater(x_sign);
|
||||
if (x_digit < abs_value) return AbsoluteLess(x_sign);
|
||||
return ComparisonResult::kEqual;
|
||||
}
|
||||
DCHECK(y->IsHeapNumber());
|
||||
double value = Handle<HeapNumber>::cast(y)->value();
|
||||
return CompareToDouble(x, value);
|
||||
}
|
||||
|
||||
ComparisonResult BigInt::CompareToDouble(Handle<BigInt> x, double y) {
|
||||
if (std::isnan(y)) return ComparisonResult::kUndefined;
|
||||
if (y == V8_INFINITY) return ComparisonResult::kLessThan;
|
||||
if (y == -V8_INFINITY) return ComparisonResult::kGreaterThan;
|
||||
bool x_sign = x->sign();
|
||||
// Note that this is different from the double's sign bit for -0. That's
|
||||
// intentional because -0 must be treated like 0.
|
||||
bool y_sign = (y < 0);
|
||||
if (x_sign != y_sign) return UnequalSign(x_sign);
|
||||
if (y == 0) {
|
||||
DCHECK(!x_sign);
|
||||
return x->is_zero() ? ComparisonResult::kEqual
|
||||
: ComparisonResult::kGreaterThan;
|
||||
}
|
||||
if (x->is_zero()) {
|
||||
DCHECK(!y_sign);
|
||||
return ComparisonResult::kLessThan;
|
||||
}
|
||||
uint64_t double_bits = bit_cast<uint64_t>(y);
|
||||
int raw_exponent =
|
||||
static_cast<int>(double_bits >> Double::kPhysicalSignificandSize) & 0x7FF;
|
||||
uint64_t mantissa = double_bits & Double::kSignificandMask;
|
||||
// Non-finite doubles are handled above.
|
||||
DCHECK_NE(raw_exponent, 0x7FF);
|
||||
int exponent = raw_exponent - 0x3FF;
|
||||
if (exponent < 0) {
|
||||
// The absolute value of the double is less than 1. Only 0n has an
|
||||
// absolute value smaller than that, but we've already covered that case.
|
||||
DCHECK(!x->is_zero());
|
||||
return AbsoluteGreater(x_sign);
|
||||
}
|
||||
int x_length = x->length();
|
||||
digit_t x_msd = x->digit(x_length - 1);
|
||||
int msd_leading_zeros = base::bits::CountLeadingZeros(x_msd);
|
||||
int x_bitlength = x_length * kDigitBits - msd_leading_zeros;
|
||||
int y_bitlength = exponent + 1;
|
||||
if (x_bitlength < y_bitlength) return AbsoluteLess(x_sign);
|
||||
if (x_bitlength > y_bitlength) return AbsoluteGreater(x_sign);
|
||||
|
||||
// At this point, we know that signs and bit lengths (i.e. position of
|
||||
// the most significant bit in exponent-free representation) are identical.
|
||||
// {x} is not zero, {y} is finite and not denormal.
|
||||
// Now we virtually convert the double to an integer by shifting its
|
||||
// mantissa according to its exponent, so it will align with the BigInt {x},
|
||||
// and then we compare them bit for bit until we find a difference or the
|
||||
// least significant bit.
|
||||
// <----- 52 ------> <-- virtual trailing zeroes -->
|
||||
// y / mantissa: 1yyyyyyyyyyyyyyyyy 0000000000000000000000000000000
|
||||
// x / digits: 0001xxxx xxxxxxxx xxxxxxxx ...
|
||||
// <--> <------>
|
||||
// msd_topbit kDigitBits
|
||||
//
|
||||
mantissa |= Double::kHiddenBit;
|
||||
const int kMantissaTopBit = 52; // 0-indexed.
|
||||
// 0-indexed position of {x}'s most significant bit within the {msd}.
|
||||
int msd_topbit = kDigitBits - 1 - msd_leading_zeros;
|
||||
DCHECK_EQ(msd_topbit, (x_bitlength - 1) % kDigitBits);
|
||||
// Shifted chunk of {mantissa} for comparing with {digit}.
|
||||
digit_t compare_mantissa;
|
||||
// Number of unprocessed bits in {mantissa}. We'll keep them shifted to
|
||||
// the left (i.e. most significant part) of the underlying uint64_t.
|
||||
int remaining_mantissa_bits = 0;
|
||||
|
||||
// First, compare the most significant digit against the beginning of
|
||||
// the mantissa.
|
||||
if (msd_topbit < kMantissaTopBit) {
|
||||
remaining_mantissa_bits = (kMantissaTopBit - msd_topbit);
|
||||
compare_mantissa = mantissa >> remaining_mantissa_bits;
|
||||
mantissa = mantissa << (64 - remaining_mantissa_bits);
|
||||
} else {
|
||||
DCHECK(msd_topbit >= kMantissaTopBit);
|
||||
compare_mantissa = mantissa << (msd_topbit - kMantissaTopBit);
|
||||
mantissa = 0;
|
||||
}
|
||||
if (x_msd > compare_mantissa) return AbsoluteGreater(x_sign);
|
||||
if (x_msd < compare_mantissa) return AbsoluteLess(x_sign);
|
||||
|
||||
// Then, compare additional digits against any remaining mantissa bits.
|
||||
for (int digit_index = x_length - 2; digit_index >= 0; digit_index--) {
|
||||
if (remaining_mantissa_bits > 0) {
|
||||
remaining_mantissa_bits -= kDigitBits;
|
||||
if (sizeof(mantissa) != sizeof(x_msd)) {
|
||||
compare_mantissa = mantissa >> (64 - kDigitBits);
|
||||
// "& 63" to appease compilers. kDigitBits is 32 here anyway.
|
||||
mantissa = mantissa << (kDigitBits & 63);
|
||||
} else {
|
||||
compare_mantissa = mantissa;
|
||||
mantissa = 0;
|
||||
}
|
||||
} else {
|
||||
compare_mantissa = 0;
|
||||
}
|
||||
digit_t digit = x->digit(digit_index);
|
||||
if (digit > compare_mantissa) return AbsoluteGreater(x_sign);
|
||||
if (digit < compare_mantissa) return AbsoluteLess(x_sign);
|
||||
}
|
||||
|
||||
// Integer parts are equal; check whether {y} has a fractional part.
|
||||
if (mantissa != 0) {
|
||||
DCHECK(remaining_mantissa_bits > 0);
|
||||
return AbsoluteLess(x_sign);
|
||||
}
|
||||
return ComparisonResult::kEqual;
|
||||
}
|
||||
|
||||
MaybeHandle<String> BigInt::ToString(Handle<BigInt> bigint, int radix) {
|
||||
Isolate* isolate = bigint->GetIsolate();
|
||||
if (bigint->is_zero()) {
|
||||
|
@ -17,7 +17,7 @@ namespace internal {
|
||||
|
||||
// UNDER CONSTRUCTION!
|
||||
// Arbitrary precision integers in JavaScript.
|
||||
class BigInt : public HeapObject {
|
||||
class V8_EXPORT_PRIVATE BigInt : public HeapObject {
|
||||
public:
|
||||
// Implementation of the Spec methods, see:
|
||||
// https://tc39.github.io/proposal-bigint/#sec-numeric-types
|
||||
@ -36,22 +36,29 @@ class BigInt : public HeapObject {
|
||||
Handle<BigInt> y);
|
||||
static MaybeHandle<BigInt> UnsignedRightShift(Handle<BigInt> x,
|
||||
Handle<BigInt> y);
|
||||
static bool LessThan(Handle<BigInt> x, Handle<BigInt> y);
|
||||
static bool Equal(BigInt* x, BigInt* y);
|
||||
// More convenient version of "bool LessThan(x, y)".
|
||||
static ComparisonResult CompareToBigInt(Handle<BigInt> x, Handle<BigInt> y);
|
||||
static bool EqualToBigInt(BigInt* x, BigInt* y);
|
||||
static Handle<BigInt> BitwiseAnd(Handle<BigInt> x, Handle<BigInt> y);
|
||||
static Handle<BigInt> BitwiseXor(Handle<BigInt> x, Handle<BigInt> y);
|
||||
static Handle<BigInt> BitwiseOr(Handle<BigInt> x, Handle<BigInt> y);
|
||||
|
||||
// Other parts of the public interface.
|
||||
static MaybeHandle<BigInt> Increment(Handle<BigInt> x);
|
||||
static MaybeHandle<BigInt> Decrement(Handle<BigInt> x);
|
||||
|
||||
// Other parts of the public interface.
|
||||
bool ToBoolean() { return !is_zero(); }
|
||||
uint32_t Hash() {
|
||||
// TODO(jkummerow): Improve this. At least use length and sign.
|
||||
return is_zero() ? 0 : ComputeIntegerHash(static_cast<uint32_t>(digit(0)));
|
||||
}
|
||||
|
||||
static bool EqualToString(Handle<BigInt> x, Handle<String> y);
|
||||
static bool EqualToNumber(Handle<BigInt> x, Handle<Object> y);
|
||||
static ComparisonResult CompareToNumber(Handle<BigInt> x, Handle<Object> y);
|
||||
// Exposed for tests, do not call directly. Use CompareToNumber() instead.
|
||||
static ComparisonResult CompareToDouble(Handle<BigInt> x, double y);
|
||||
|
||||
DECL_CAST(BigInt)
|
||||
DECL_VERIFIER(BigInt)
|
||||
DECL_PRINTER(BigInt)
|
||||
|
@ -19,7 +19,7 @@ RUNTIME_FUNCTION(Runtime_BigIntEqual) {
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1);
|
||||
bool result = lhs->IsBigInt() && rhs->IsBigInt() &&
|
||||
BigInt::Equal(BigInt::cast(*lhs), BigInt::cast(*rhs));
|
||||
BigInt::EqualToBigInt(BigInt::cast(*lhs), BigInt::cast(*rhs));
|
||||
return *isolate->factory()->ToBoolean(result);
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ v8_source_set("unittests_sources") {
|
||||
"base/sys-info-unittest.cc",
|
||||
"base/template-utils-unittest.cc",
|
||||
"base/utils/random-number-generator-unittest.cc",
|
||||
"bigint-unittest.cc",
|
||||
"cancelable-tasks-unittest.cc",
|
||||
"char-predicates-unittest.cc",
|
||||
"code-stub-assembler-unittest.cc",
|
||||
|
111
test/unittests/bigint-unittest.cc
Normal file
111
test/unittests/bigint-unittest.cc
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright 2017 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 <cmath>
|
||||
|
||||
#include "src/conversions.h"
|
||||
#include "src/factory.h"
|
||||
#include "src/isolate.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/bigint-inl.h"
|
||||
#include "test/unittests/test-utils.h"
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
typedef TestWithIsolate BigIntWithIsolate;
|
||||
|
||||
void Compare(Handle<BigInt> x, double value, ComparisonResult expected) {
|
||||
CHECK_EQ(expected, BigInt::CompareToDouble(x, value));
|
||||
}
|
||||
|
||||
TEST_F(BigIntWithIsolate, CompareToDouble) {
|
||||
Factory* factory = isolate()->factory();
|
||||
Handle<BigInt> zero = factory->NewBigIntFromInt(0);
|
||||
Handle<BigInt> one = factory->NewBigIntFromInt(1);
|
||||
Handle<BigInt> minus_one = factory->NewBigIntFromInt(-1);
|
||||
|
||||
// Non-finite doubles.
|
||||
Compare(zero, std::nan(""), ComparisonResult::kUndefined);
|
||||
Compare(one, INFINITY, ComparisonResult::kLessThan);
|
||||
Compare(one, -INFINITY, ComparisonResult::kGreaterThan);
|
||||
|
||||
// Unequal sign.
|
||||
Compare(one, -1, ComparisonResult::kGreaterThan);
|
||||
Compare(minus_one, 1, ComparisonResult::kLessThan);
|
||||
|
||||
// Cases involving zero.
|
||||
Compare(zero, 0, ComparisonResult::kEqual);
|
||||
Compare(zero, -0, ComparisonResult::kEqual);
|
||||
Compare(one, 0, ComparisonResult::kGreaterThan);
|
||||
Compare(minus_one, 0, ComparisonResult::kLessThan);
|
||||
Compare(zero, 1, ComparisonResult::kLessThan);
|
||||
Compare(zero, -1, ComparisonResult::kGreaterThan);
|
||||
|
||||
// Small doubles.
|
||||
Compare(zero, 0.25, ComparisonResult::kLessThan);
|
||||
Compare(one, 0.5, ComparisonResult::kGreaterThan);
|
||||
Compare(one, -0.5, ComparisonResult::kGreaterThan);
|
||||
Compare(zero, -0.25, ComparisonResult::kGreaterThan);
|
||||
Compare(minus_one, -0.5, ComparisonResult::kLessThan);
|
||||
|
||||
// Different bit lengths.
|
||||
Handle<BigInt> four = factory->NewBigIntFromInt(4);
|
||||
Handle<BigInt> minus_five = factory->NewBigIntFromInt(-5);
|
||||
Compare(four, 3.9, ComparisonResult::kGreaterThan);
|
||||
Compare(four, 1.5, ComparisonResult::kGreaterThan);
|
||||
Compare(four, 8, ComparisonResult::kLessThan);
|
||||
Compare(four, 16, ComparisonResult::kLessThan);
|
||||
Compare(minus_five, -4.9, ComparisonResult::kLessThan);
|
||||
Compare(minus_five, -4, ComparisonResult::kLessThan);
|
||||
Compare(minus_five, -25, ComparisonResult::kGreaterThan);
|
||||
|
||||
// Same bit length, difference in first digit.
|
||||
double big_double = 4428155326412785451008.0;
|
||||
Handle<BigInt> big =
|
||||
StringToBigInt(isolate(), "0xF10D00000000000000").ToHandleChecked();
|
||||
Compare(big, big_double, ComparisonResult::kGreaterThan);
|
||||
big = StringToBigInt(isolate(), "0xE00D00000000000000").ToHandleChecked();
|
||||
Compare(big, big_double, ComparisonResult::kLessThan);
|
||||
|
||||
double other_double = -13758438578910658560.0;
|
||||
Handle<BigInt> other =
|
||||
StringToBigInt(isolate(), "-0xBEEFC1FE00000000").ToHandleChecked();
|
||||
Compare(other, other_double, ComparisonResult::kGreaterThan);
|
||||
other = StringToBigInt(isolate(), "-0xBEEFCBFE00000000").ToHandleChecked();
|
||||
Compare(other, other_double, ComparisonResult::kLessThan);
|
||||
|
||||
// Same bit length, difference in non-first digit.
|
||||
big = StringToBigInt(isolate(), "0xF00D00000000000001").ToHandleChecked();
|
||||
Compare(big, big_double, ComparisonResult::kGreaterThan);
|
||||
big = StringToBigInt(isolate(), "0xF00A00000000000000").ToHandleChecked();
|
||||
Compare(big, big_double, ComparisonResult::kLessThan);
|
||||
|
||||
other = StringToBigInt(isolate(), "-0xBEEFCAFE00000001").ToHandleChecked();
|
||||
Compare(other, other_double, ComparisonResult::kLessThan);
|
||||
|
||||
// Same bit length, difference in fractional part.
|
||||
Compare(one, 1.5, ComparisonResult::kLessThan);
|
||||
Compare(minus_one, -1.25, ComparisonResult::kGreaterThan);
|
||||
big = factory->NewBigIntFromInt(0xF00D00);
|
||||
Compare(big, 15731968.125, ComparisonResult::kLessThan);
|
||||
Compare(big, 15731967.875, ComparisonResult::kGreaterThan);
|
||||
big = StringToBigInt(isolate(), "0x123456789ab").ToHandleChecked();
|
||||
Compare(big, 1250999896491.125, ComparisonResult::kLessThan);
|
||||
|
||||
// Equality!
|
||||
Compare(one, 1, ComparisonResult::kEqual);
|
||||
Compare(minus_one, -1, ComparisonResult::kEqual);
|
||||
big = StringToBigInt(isolate(), "0xF00D00000000000000").ToHandleChecked();
|
||||
Compare(big, big_double, ComparisonResult::kEqual);
|
||||
|
||||
Handle<BigInt> two_52 =
|
||||
StringToBigInt(isolate(), "0x10000000000000").ToHandleChecked();
|
||||
Compare(two_52, 4503599627370496.0, ComparisonResult::kEqual);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -36,6 +36,7 @@
|
||||
'base/sys-info-unittest.cc',
|
||||
'base/template-utils-unittest.cc',
|
||||
'base/utils/random-number-generator-unittest.cc',
|
||||
'bigint-unittest.cc',
|
||||
'cancelable-tasks-unittest.cc',
|
||||
'char-predicates-unittest.cc',
|
||||
"code-stub-assembler-unittest.cc",
|
||||
|
Loading…
Reference in New Issue
Block a user