| 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 | 60 |
| 61 void Bignum::AssignUInt64(uint64_t value) { | 61 void Bignum::AssignUInt64(uint64_t value) { |
| 62 const int kUInt64Size = 64; | 62 const int kUInt64Size = 64; |
| 63 | 63 |
| 64 Zero(); | 64 Zero(); |
| 65 if (value == 0) return; | 65 if (value == 0) return; |
| 66 | 66 |
| 67 int needed_bigits = kUInt64Size / kBigitSize + 1; | 67 int needed_bigits = kUInt64Size / kBigitSize + 1; |
| 68 EnsureCapacity(needed_bigits); | 68 EnsureCapacity(needed_bigits); |
| 69 for (int i = 0; i < needed_bigits; ++i) { | 69 for (int i = 0; i < needed_bigits; ++i) { |
| 70 bigits_[i] = value & kBigitMask; | 70 bigits_[i] = static_cast<Chunk>(value & kBigitMask); |
| 71 value = value >> kBigitSize; | 71 value = value >> kBigitSize; |
| 72 } | 72 } |
| 73 used_digits_ = needed_bigits; | 73 used_digits_ = needed_bigits; |
| 74 Clamp(); | 74 Clamp(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 void Bignum::AssignBignum(const Bignum& other) { | 78 void Bignum::AssignBignum(const Bignum& other) { |
| 79 exponent_ = other.exponent_; | 79 exponent_ = other.exponent_; |
| 80 for (int i = 0; i < other.used_digits_; ++i) { | 80 for (int i = 0; i < other.used_digits_; ++i) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 // Assert that this number + 1 (for the carry) fits into double chunk. | 259 // Assert that this number + 1 (for the carry) fits into double chunk. |
| 260 ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1); | 260 ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1); |
| 261 DoubleChunk carry = 0; | 261 DoubleChunk carry = 0; |
| 262 for (int i = 0; i < used_digits_; ++i) { | 262 for (int i = 0; i < used_digits_; ++i) { |
| 263 DoubleChunk product = static_cast<DoubleChunk>(factor) * bigits_[i] + carry; | 263 DoubleChunk product = static_cast<DoubleChunk>(factor) * bigits_[i] + carry; |
| 264 bigits_[i] = static_cast<Chunk>(product & kBigitMask); | 264 bigits_[i] = static_cast<Chunk>(product & kBigitMask); |
| 265 carry = (product >> kBigitSize); | 265 carry = (product >> kBigitSize); |
| 266 } | 266 } |
| 267 while (carry != 0) { | 267 while (carry != 0) { |
| 268 EnsureCapacity(used_digits_ + 1); | 268 EnsureCapacity(used_digits_ + 1); |
| 269 bigits_[used_digits_] = carry & kBigitMask; | 269 bigits_[used_digits_] = static_cast<Chunk>(carry & kBigitMask); |
| 270 used_digits_++; | 270 used_digits_++; |
| 271 carry >>= kBigitSize; | 271 carry >>= kBigitSize; |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 | 274 |
| 275 | 275 |
| 276 void Bignum::MultiplyByUInt64(uint64_t factor) { | 276 void Bignum::MultiplyByUInt64(uint64_t factor) { |
| 277 if (factor == 1) return; | 277 if (factor == 1) return; |
| 278 if (factor == 0) { | 278 if (factor == 0) { |
| 279 Zero(); | 279 Zero(); |
| 280 return; | 280 return; |
| 281 } | 281 } |
| 282 ASSERT(kBigitSize < 32); | 282 ASSERT(kBigitSize < 32); |
| 283 uint64_t carry = 0; | 283 uint64_t carry = 0; |
| 284 uint64_t low = factor & 0xFFFFFFFF; | 284 uint64_t low = factor & 0xFFFFFFFF; |
| 285 uint64_t high = factor >> 32; | 285 uint64_t high = factor >> 32; |
| 286 for (int i = 0; i < used_digits_; ++i) { | 286 for (int i = 0; i < used_digits_; ++i) { |
| 287 uint64_t product_low = low * bigits_[i]; | 287 uint64_t product_low = low * bigits_[i]; |
| 288 uint64_t product_high = high * bigits_[i]; | 288 uint64_t product_high = high * bigits_[i]; |
| 289 uint64_t tmp = (carry & kBigitMask) + product_low; | 289 uint64_t tmp = (carry & kBigitMask) + product_low; |
| 290 bigits_[i] = tmp & kBigitMask; | 290 bigits_[i] = static_cast<Chunk>(tmp & kBigitMask); |
| 291 carry = (carry >> kBigitSize) + (tmp >> kBigitSize) + | 291 carry = (carry >> kBigitSize) + (tmp >> kBigitSize) + |
| 292 (product_high << (32 - kBigitSize)); | 292 (product_high << (32 - kBigitSize)); |
| 293 } | 293 } |
| 294 while (carry != 0) { | 294 while (carry != 0) { |
| 295 EnsureCapacity(used_digits_ + 1); | 295 EnsureCapacity(used_digits_ + 1); |
| 296 bigits_[used_digits_] = carry & kBigitMask; | 296 bigits_[used_digits_] = static_cast<Chunk>(carry & kBigitMask); |
| 297 used_digits_++; | 297 used_digits_++; |
| 298 carry >>= kBigitSize; | 298 carry >>= kBigitSize; |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 | 301 |
| 302 | 302 |
| 303 void Bignum::MultiplyByPowerOfTen(int exponent) { | 303 void Bignum::MultiplyByPowerOfTen(int exponent) { |
| 304 const uint64_t kFive27 = V8_2PART_UINT64_C(0x6765c793, fa10079d); | 304 const uint64_t kFive27 = V8_2PART_UINT64_C(0x6765c793, fa10079d); |
| 305 const uint16_t kFive1 = 5; | 305 const uint16_t kFive1 = 5; |
| 306 const uint16_t kFive2 = kFive1 * 5; | 306 const uint16_t kFive2 = kFive1 * 5; |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 for (int i = 0; i < factor; ++i) { | 741 for (int i = 0; i < factor; ++i) { |
| 742 SubtractBignum(other); | 742 SubtractBignum(other); |
| 743 } | 743 } |
| 744 return; | 744 return; |
| 745 } | 745 } |
| 746 Chunk borrow = 0; | 746 Chunk borrow = 0; |
| 747 int exponent_diff = other.exponent_ - exponent_; | 747 int exponent_diff = other.exponent_ - exponent_; |
| 748 for (int i = 0; i < other.used_digits_; ++i) { | 748 for (int i = 0; i < other.used_digits_; ++i) { |
| 749 DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i]; | 749 DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i]; |
| 750 DoubleChunk remove = borrow + product; | 750 DoubleChunk remove = borrow + product; |
| 751 Chunk difference = bigits_[i + exponent_diff] - (remove & kBigitMask); | 751 Chunk difference = |
| 752 bigits_[i + exponent_diff] - static_cast<Chunk>(remove & kBigitMask); |
| 752 bigits_[i + exponent_diff] = difference & kBigitMask; | 753 bigits_[i + exponent_diff] = difference & kBigitMask; |
| 753 borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) + | 754 borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) + |
| 754 (remove >> kBigitSize)); | 755 (remove >> kBigitSize)); |
| 755 } | 756 } |
| 756 for (int i = other.used_digits_ + exponent_diff; i < used_digits_; ++i) { | 757 for (int i = other.used_digits_ + exponent_diff; i < used_digits_; ++i) { |
| 757 if (borrow == 0) return; | 758 if (borrow == 0) return; |
| 758 Chunk difference = bigits_[i] - borrow; | 759 Chunk difference = bigits_[i] - borrow; |
| 759 bigits_[i] = difference & kBigitMask; | 760 bigits_[i] = difference & kBigitMask; |
| 760 borrow = difference >> (kChunkSize - 1); | 761 borrow = difference >> (kChunkSize - 1); |
| 761 ++i; | 762 ++i; |
| 762 } | 763 } |
| 763 Clamp(); | 764 Clamp(); |
| 764 } | 765 } |
| 765 | 766 |
| 766 | 767 |
| 767 } } // namespace v8::internal | 768 } } // namespace v8::internal |
| OLD | NEW |