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 |