| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 Bignum::Bignum() | 33 Bignum::Bignum() |
| 34 : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) { | 34 : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) { |
| 35 for (int i = 0; i < kBigitCapacity; ++i) { | 35 for (int i = 0; i < kBigitCapacity; ++i) { |
| 36 bigits_[i] = 0; | 36 bigits_[i] = 0; |
| 37 } | 37 } |
| 38 } | 38 } |
| 39 | 39 |
| 40 | 40 |
| 41 template<typename S> | 41 template<typename S> |
| 42 static int BitSize(S value) { | 42 static int BitSize(S value) { |
| 43 (void) value; // Mark variable as used. |
| 43 return 8 * sizeof(value); | 44 return 8 * sizeof(value); |
| 44 } | 45 } |
| 45 | 46 |
| 46 // Guaranteed to lie in one Bigit. | 47 // Guaranteed to lie in one Bigit. |
| 47 void Bignum::AssignUInt16(uint16_t value) { | 48 void Bignum::AssignUInt16(uint16_t value) { |
| 48 ASSERT(kBigitSize >= BitSize(value)); | 49 ASSERT(kBigitSize >= BitSize(value)); |
| 49 Zero(); | 50 Zero(); |
| 50 if (value == 0) return; | 51 if (value == 0) return; |
| 51 | 52 |
| 52 EnsureCapacity(1); | 53 EnsureCapacity(1); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 uint64_t digits = ReadUInt64(value, pos, length); | 116 uint64_t digits = ReadUInt64(value, pos, length); |
| 116 MultiplyByPowerOfTen(length); | 117 MultiplyByPowerOfTen(length); |
| 117 AddUInt64(digits); | 118 AddUInt64(digits); |
| 118 Clamp(); | 119 Clamp(); |
| 119 } | 120 } |
| 120 | 121 |
| 121 | 122 |
| 122 static int HexCharValue(char c) { | 123 static int HexCharValue(char c) { |
| 123 if ('0' <= c && c <= '9') return c - '0'; | 124 if ('0' <= c && c <= '9') return c - '0'; |
| 124 if ('a' <= c && c <= 'f') return 10 + c - 'a'; | 125 if ('a' <= c && c <= 'f') return 10 + c - 'a'; |
| 125 if ('A' <= c && c <= 'F') return 10 + c - 'A'; | 126 ASSERT('A' <= c && c <= 'F'); |
| 126 UNREACHABLE(); | 127 return 10 + c - 'A'; |
| 127 return 0; // To make compiler happy. | |
| 128 } | 128 } |
| 129 | 129 |
| 130 | 130 |
| 131 void Bignum::AssignHexString(Vector<const char> value) { | 131 void Bignum::AssignHexString(Vector<const char> value) { |
| 132 Zero(); | 132 Zero(); |
| 133 int length = value.length(); | 133 int length = value.length(); |
| 134 | 134 |
| 135 int needed_bigits = length * 4 / kBigitSize + 1; | 135 int needed_bigits = length * 4 / kBigitSize + 1; |
| 136 EnsureCapacity(needed_bigits); | 136 EnsureCapacity(needed_bigits); |
| 137 int string_index = length - 1; | 137 int string_index = length - 1; |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 return 0; | 494 return 0; |
| 495 } | 495 } |
| 496 | 496 |
| 497 Align(other); | 497 Align(other); |
| 498 | 498 |
| 499 uint16_t result = 0; | 499 uint16_t result = 0; |
| 500 | 500 |
| 501 // Start by removing multiples of 'other' until both numbers have the same | 501 // Start by removing multiples of 'other' until both numbers have the same |
| 502 // number of digits. | 502 // number of digits. |
| 503 while (BigitLength() > other.BigitLength()) { | 503 while (BigitLength() > other.BigitLength()) { |
| 504 // This naive approach is extremely inefficient if the this divided other | 504 // This naive approach is extremely inefficient if `this` divided by other |
| 505 // might be big. This function is implemented for doubleToString where | 505 // is big. This function is implemented for doubleToString where |
| 506 // the result should be small (less than 10). | 506 // the result should be small (less than 10). |
| 507 ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16)); | 507 ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16)); |
| 508 ASSERT(bigits_[used_digits_ - 1] < 0x10000); |
| 508 // Remove the multiples of the first digit. | 509 // Remove the multiples of the first digit. |
| 509 // Example this = 23 and other equals 9. -> Remove 2 multiples. | 510 // Example this = 23 and other equals 9. -> Remove 2 multiples. |
| 510 result += bigits_[used_digits_ - 1]; | 511 result += static_cast<uint16_t>(bigits_[used_digits_ - 1]); |
| 511 SubtractTimes(other, bigits_[used_digits_ - 1]); | 512 SubtractTimes(other, bigits_[used_digits_ - 1]); |
| 512 } | 513 } |
| 513 | 514 |
| 514 ASSERT(BigitLength() == other.BigitLength()); | 515 ASSERT(BigitLength() == other.BigitLength()); |
| 515 | 516 |
| 516 // Both bignums are at the same length now. | 517 // Both bignums are at the same length now. |
| 517 // Since other has more than 0 digits we know that the access to | 518 // Since other has more than 0 digits we know that the access to |
| 518 // bigits_[used_digits_ - 1] is safe. | 519 // bigits_[used_digits_ - 1] is safe. |
| 519 Chunk this_bigit = bigits_[used_digits_ - 1]; | 520 Chunk this_bigit = bigits_[used_digits_ - 1]; |
| 520 Chunk other_bigit = other.bigits_[other.used_digits_ - 1]; | 521 Chunk other_bigit = other.bigits_[other.used_digits_ - 1]; |
| 521 | 522 |
| 522 if (other.used_digits_ == 1) { | 523 if (other.used_digits_ == 1) { |
| 523 // Shortcut for easy (and common) case. | 524 // Shortcut for easy (and common) case. |
| 524 int quotient = this_bigit / other_bigit; | 525 int quotient = this_bigit / other_bigit; |
| 525 bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient; | 526 bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient; |
| 526 result += quotient; | 527 ASSERT(quotient < 0x10000); |
| 528 result += static_cast<uint16_t>(quotient); |
| 527 Clamp(); | 529 Clamp(); |
| 528 return result; | 530 return result; |
| 529 } | 531 } |
| 530 | 532 |
| 531 int division_estimate = this_bigit / (other_bigit + 1); | 533 int division_estimate = this_bigit / (other_bigit + 1); |
| 532 result += division_estimate; | 534 ASSERT(division_estimate < 0x10000); |
| 535 result += static_cast<uint16_t>(division_estimate); |
| 533 SubtractTimes(other, division_estimate); | 536 SubtractTimes(other, division_estimate); |
| 534 | 537 |
| 535 if (other_bigit * (division_estimate + 1) > this_bigit) { | 538 if (other_bigit * (division_estimate + 1) > this_bigit) { |
| 536 // No need to even try to subtract. Even if other's remaining digits were 0 | 539 // No need to even try to subtract. Even if other's remaining digits were 0 |
| 537 // another subtraction would be too much. | 540 // another subtraction would be too much. |
| 538 return result; | 541 return result; |
| 539 } | 542 } |
| 540 | 543 |
| 541 while (LessEqual(other, *this)) { | 544 while (LessEqual(other, *this)) { |
| 542 SubtractBignum(other); | 545 SubtractBignum(other); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 553 while (number != 0) { | 556 while (number != 0) { |
| 554 number >>= 4; | 557 number >>= 4; |
| 555 result++; | 558 result++; |
| 556 } | 559 } |
| 557 return result; | 560 return result; |
| 558 } | 561 } |
| 559 | 562 |
| 560 | 563 |
| 561 static char HexCharOfValue(int value) { | 564 static char HexCharOfValue(int value) { |
| 562 ASSERT(0 <= value && value <= 16); | 565 ASSERT(0 <= value && value <= 16); |
| 563 if (value < 10) return value + '0'; | 566 if (value < 10) return static_cast<char>(value + '0'); |
| 564 return value - 10 + 'A'; | 567 return static_cast<char>(value - 10 + 'A'); |
| 565 } | 568 } |
| 566 | 569 |
| 567 | 570 |
| 568 bool Bignum::ToHexString(char* buffer, int buffer_size) const { | 571 bool Bignum::ToHexString(char* buffer, int buffer_size) const { |
| 569 ASSERT(IsClamped()); | 572 ASSERT(IsClamped()); |
| 570 // Each bigit must be printable as separate hex-character. | 573 // Each bigit must be printable as separate hex-character. |
| 571 ASSERT(kBigitSize % 4 == 0); | 574 ASSERT(kBigitSize % 4 == 0); |
| 572 const int kHexCharsPerBigit = kBigitSize / 4; | 575 const int kHexCharsPerBigit = kBigitSize / 4; |
| 573 | 576 |
| 574 if (used_digits_ == 0) { | 577 if (used_digits_ == 0) { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 if (borrow == 0) return; | 757 if (borrow == 0) return; |
| 755 Chunk difference = bigits_[i] - borrow; | 758 Chunk difference = bigits_[i] - borrow; |
| 756 bigits_[i] = difference & kBigitMask; | 759 bigits_[i] = difference & kBigitMask; |
| 757 borrow = difference >> (kChunkSize - 1); | 760 borrow = difference >> (kChunkSize - 1); |
| 758 } | 761 } |
| 759 Clamp(); | 762 Clamp(); |
| 760 } | 763 } |
| 761 | 764 |
| 762 | 765 |
| 763 } // namespace double_conversion | 766 } // namespace double_conversion |
| OLD | NEW |