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 static_cast<Chunk>(bigits_[i + exponent_diff] - (remove & kBigitMask)); | |
William Hesse
2011/02/05 19:38:12
Can this static_cast<Chunk> be applied just to (re
| |
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 |