13 : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
21 return 8 *
sizeof(
value);
28 if (value == 0)
return;
36 const int kUInt64Size = 64;
39 if (value == 0)
return;
41 int needed_bigits = kUInt64Size /
kBigitSize + 1;
43 for (
int i = 0;
i < needed_bigits; ++
i) {
53 for (
int i = 0;
i < other.used_digits_; ++
i) {
66 int to = from + digits_to_read;
68 for (
int i = from;
i <
to; ++
i) {
69 int digit = buffer[
i] -
'0';
70 DCHECK(0 <= digit && digit <= 9);
80 int length = value.length();
97 if (
'0' <= c && c <=
'9')
return c -
'0';
98 if (
'a' <= c && c <=
'f')
return 10 + c -
'a';
99 if (
'A' <= c && c <=
'F')
return 10 + c -
'A';
105 int length = value.length();
107 int needed_bigits = length * 4 /
kBigitSize + 1;
109 int string_index = length - 1;
110 for (
int i = 0;
i < needed_bigits - 1; ++
i) {
112 Chunk current_bigit = 0;
114 current_bigit +=
HexCharValue(value[string_index--]) << (j * 4);
120 Chunk most_significant_bigit = 0;
121 for (
int j = 0; j <= string_index; ++j) {
122 most_significant_bigit <<= 4;
125 if (most_significant_bigit != 0) {
133 if (operand == 0)
return;
141 DCHECK(other.IsClamped());
161 int bigit_pos = other.exponent_ -
exponent_;
163 for (
int i = 0;
i < other.used_digits_; ++
i) {
182 DCHECK(other.IsClamped());
191 for (
i = 0;
i < other.used_digits_; ++
i) {
192 DCHECK((borrow == 0) || (borrow == 1));
197 while (borrow != 0) {
215 if (factor == 1)
return;
240 if (factor == 1)
return;
247 uint64_t low = factor & 0xFFFFFFFF;
248 uint64_t high = factor >> 32;
250 uint64_t product_low = low *
bigits_[
i];
251 uint64_t product_high = high *
bigits_[
i];
252 uint64_t tmp = (carry &
kBigitMask) + product_low;
266 const uint64_t kFive27 = 0x6765'C793'FA10'079D;
267 const uint16_t kFive1 = 5;
268 const uint16_t kFive2 = kFive1 * 5;
269 const uint16_t kFive3 = kFive2 * 5;
270 const uint16_t kFive4 = kFive3 * 5;
271 const uint16_t kFive5 = kFive4 * 5;
272 const uint16_t kFive6 = kFive5 * 5;
273 const uint32_t kFive7 = kFive6 * 5;
274 const uint32_t kFive8 = kFive7 * 5;
275 const uint32_t kFive9 = kFive8 * 5;
276 const uint32_t kFive10 = kFive9 * 5;
277 const uint32_t kFive11 = kFive10 * 5;
278 const uint32_t kFive12 = kFive11 * 5;
279 const uint32_t kFive13 = kFive12 * 5;
280 const uint32_t kFive1_to_12[] = {kFive1, kFive2, kFive3, kFive4,
281 kFive5, kFive6, kFive7, kFive8,
282 kFive9, kFive10, kFive11, kFive12};
285 if (exponent == 0)
return;
289 int remaining_exponent = exponent;
290 while (remaining_exponent >= 27) {
292 remaining_exponent -= 27;
294 while (remaining_exponent >= 13) {
296 remaining_exponent -= 13;
298 if (remaining_exponent > 0) {
334 int bigit_index1 =
i;
335 int bigit_index2 = 0;
337 while (bigit_index1 >= 0) {
340 accumulator +=
static_cast<DoubleChunk>(chunk1) * chunk2;
349 int bigit_index2 =
i - bigit_index1;
355 accumulator +=
static_cast<DoubleChunk>(chunk1) * chunk2;
378 if (power_exponent == 0) {
387 while ((
base & 1) == 0) {
393 while (tmp_base != 0) {
397 int final_size = bit_size * power_exponent;
403 while (power_exponent >=
mask)
mask <<= 1;
409 uint64_t this_value =
base;
411 bool delayed_multipliciation =
false;
412 const uint64_t max_32bits = 0xFFFFFFFF;
413 while (
mask != 0 && this_value <= max_32bits) {
414 this_value = this_value * this_value;
417 if ((power_exponent &
mask) != 0) {
418 uint64_t base_bits_mask =
419 ~((
static_cast<uint64_t
>(1) << (64 - bit_size)) - 1);
420 bool high_bits_zero = (this_value & base_bits_mask) == 0;
421 if (high_bits_zero) {
424 delayed_multipliciation =
true;
430 if (delayed_multipliciation) {
437 if ((power_exponent &
mask) != 0) {
450 DCHECK(other.IsClamped());
482 Chunk other_bigit = other.bigits_[other.used_digits_ - 1];
484 if (other.used_digits_ == 1) {
486 int quotient = this_bigit / other_bigit;
493 int division_estimate = this_bigit / (other_bigit + 1);
494 result += division_estimate;
497 if (other_bigit * (division_estimate + 1) > this_bigit) {
514 while (number != 0) {
528 if (buffer_size < 2)
return false;
534 int needed_chars = (
BigitLength() - 1) * kHexCharsPerBigit +
536 if (needed_chars > buffer_size)
return false;
537 int string_index = needed_chars - 1;
538 buffer[string_index--] =
'\0';
540 for (
int j = 0; j < kHexCharsPerBigit; ++j) {
541 buffer[string_index--] =
'0';
546 for (
int j = 0; j < kHexCharsPerBigit; ++j) {
553 while (most_significant_bigit != 0) {
554 buffer[string_index--] =
HexCharOfValue(most_significant_bigit & 0xF);
555 most_significant_bigit >>= 4;
569 int bigit_length_a = a.BigitLength();
571 if (bigit_length_a < bigit_length_b)
return -1;
572 if (bigit_length_a > bigit_length_b)
return +1;
573 for (
int i = bigit_length_a - 1;
i >= std::min(a.exponent_, b.
exponent_);
575 Chunk bigit_a = a.BigitAt(
i);
577 if (bigit_a < bigit_b)
return -1;
578 if (bigit_a > bigit_b)
return +1;
591 if (a.BigitLength() + 1 < c.
BigitLength())
return -1;
604 Chunk chunk_a = a.BigitAt(
i);
607 Chunk sum = chunk_a + chunk_b;
608 if (sum > chunk_c + borrow) {
611 borrow = chunk_c + borrow - sum;
612 if (borrow > 1)
return -1;
616 if (borrow == 0)
return 0;
650 int zero_digits =
exponent_ - other.exponent_;
655 for (
int i = 0;
i < zero_digits; ++
i) {
690 for (
int i = 0;
i < factor; ++
i) {
696 int exponent_diff = other.exponent_ -
exponent_;
697 for (
int i = 0;
i < other.used_digits_; ++
i) {
706 for (
int i = other.used_digits_ + exponent_diff;
i <
used_digits_; ++
i) {
707 if (borrow == 0)
return;
void AssignUInt16(uint16_t value)
static bool LessEqual(const Bignum &a, const Bignum &b)
void AssignHexString(Vector< const char > value)
uint16_t DivideModuloIntBignum(const Bignum &other)
void SubtractBignum(const Bignum &other)
void SubtractTimes(const Bignum &other, int factor)
void AddBignum(const Bignum &other)
static const int kDoubleChunkSize
void Align(const Bignum &other)
void AddUInt64(uint64_t operand)
void MultiplyByUInt64(uint64_t factor)
void AssignDecimalString(Vector< const char > value)
static const int kBigitSize
void BigitsShiftLeft(int shift_amount)
void AssignUInt64(uint64_t value)
void MultiplyByPowerOfTen(int exponent)
static bool Equal(const Bignum &a, const Bignum &b)
bool ToHexString(char *buffer, int buffer_size) const
static const Chunk kBigitMask
void MultiplyByUInt32(uint32_t factor)
void AssignBignum(const Bignum &other)
void EnsureCapacity(int size)
void ShiftLeft(int shift_amount)
Chunk BigitAt(int index) const
static const int kChunkSize
void AssignPowerUInt16(uint16_t base, int exponent)
static const int kBigitCapacity
static int Compare(const Bignum &a, const Bignum &b)
static int PlusCompare(const Bignum &a, const Bignum &b, const Bignum &c)
std::optional< TNode< JSArray > > a
ZoneVector< RpoNumber > & result
static uint64_t ReadUInt64(Vector< const char > buffer, int from, int digits_to_read)
char HexCharOfValue(int value)
static int HexCharValue(char c)
static const int kMaxUint64DecimalDigits
static int SizeInHexChars(S number)
static int BitSize(S value)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
std::unique_ptr< ValueMirror > value