Line data Source code
1 : // Copyright 2010 the V8 project authors. All rights reserved.
2 : // Redistribution and use in source and binary forms, with or without
3 : // modification, are permitted provided that the following conditions are
4 : // met:
5 : //
6 : // * Redistributions of source code must retain the above copyright
7 : // notice, this list of conditions and the following disclaimer.
8 : // * Redistributions in binary form must reproduce the above
9 : // copyright notice, this list of conditions and the following
10 : // disclaimer in the documentation and/or other materials provided
11 : // with the distribution.
12 : // * Neither the name of Google Inc. nor the names of its
13 : // contributors may be used to endorse or promote products derived
14 : // from this software without specific prior written permission.
15 : //
16 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 :
28 : #ifndef DOUBLE_CONVERSION_BIGNUM_H_
29 : #define DOUBLE_CONVERSION_BIGNUM_H_
30 :
31 : #include "utils.h"
32 :
33 : namespace double_conversion {
34 :
35 : class Bignum {
36 : public:
37 : // 3584 = 128 * 28. We can represent 2^3584 > 10^1000 accurately.
38 : // This bignum can encode much bigger numbers, since it contains an
39 : // exponent.
40 : static const int kMaxSignificantBits = 3584;
41 :
42 : Bignum();
43 : void AssignUInt16(uint16_t value);
44 : void AssignUInt64(uint64_t value);
45 : void AssignBignum(const Bignum& other);
46 :
47 : void AssignDecimalString(Vector<const char> value);
48 : void AssignHexString(Vector<const char> value);
49 :
50 : void AssignPowerUInt16(uint16_t base, int exponent);
51 :
52 : void AddUInt64(uint64_t operand);
53 : void AddBignum(const Bignum& other);
54 : // Precondition: this >= other.
55 : void SubtractBignum(const Bignum& other);
56 :
57 : void Square();
58 : void ShiftLeft(int shift_amount);
59 : void MultiplyByUInt32(uint32_t factor);
60 : void MultiplyByUInt64(uint64_t factor);
61 : void MultiplyByPowerOfTen(int exponent);
62 0 : void Times10() { return MultiplyByUInt32(10); }
63 : // Pseudocode:
64 : // int result = this / other;
65 : // this = this % other;
66 : // In the worst case this function is in O(this/other).
67 : uint16_t DivideModuloIntBignum(const Bignum& other);
68 :
69 : bool ToHexString(char* buffer, int buffer_size) const;
70 :
71 : // Returns
72 : // -1 if a < b,
73 : // 0 if a == b, and
74 : // +1 if a > b.
75 : static int Compare(const Bignum& a, const Bignum& b);
76 0 : static bool Equal(const Bignum& a, const Bignum& b) {
77 0 : return Compare(a, b) == 0;
78 : }
79 0 : static bool LessEqual(const Bignum& a, const Bignum& b) {
80 0 : return Compare(a, b) <= 0;
81 : }
82 0 : static bool Less(const Bignum& a, const Bignum& b) {
83 0 : return Compare(a, b) < 0;
84 : }
85 : // Returns Compare(a + b, c);
86 : static int PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c);
87 : // Returns a + b == c
88 : static bool PlusEqual(const Bignum& a, const Bignum& b, const Bignum& c) {
89 : return PlusCompare(a, b, c) == 0;
90 : }
91 : // Returns a + b <= c
92 : static bool PlusLessEqual(const Bignum& a, const Bignum& b, const Bignum& c) {
93 : return PlusCompare(a, b, c) <= 0;
94 : }
95 : // Returns a + b < c
96 : static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) {
97 : return PlusCompare(a, b, c) < 0;
98 : }
99 : private:
100 : typedef uint32_t Chunk;
101 : typedef uint64_t DoubleChunk;
102 :
103 : static const int kChunkSize = sizeof(Chunk) * 8;
104 : static const int kDoubleChunkSize = sizeof(DoubleChunk) * 8;
105 : // With bigit size of 28 we loose some bits, but a double still fits easily
106 : // into two chunks, and more importantly we can use the Comba multiplication.
107 : static const int kBigitSize = 28;
108 : static const Chunk kBigitMask = (1 << kBigitSize) - 1;
109 : // Every instance allocates kBigitLength chunks on the stack. Bignums cannot
110 : // grow. There are no checks if the stack-allocated space is sufficient.
111 : static const int kBigitCapacity = kMaxSignificantBits / kBigitSize;
112 :
113 0 : void EnsureCapacity(int size) {
114 0 : if (size > kBigitCapacity) {
115 0 : UNREACHABLE();
116 : }
117 0 : }
118 : void Align(const Bignum& other);
119 : void Clamp();
120 : bool IsClamped() const;
121 : void Zero();
122 : // Requires this to have enough capacity (no tests done).
123 : // Updates used_digits_ if necessary.
124 : // shift_amount must be < kBigitSize.
125 : void BigitsShiftLeft(int shift_amount);
126 : // BigitLength includes the "hidden" digits encoded in the exponent.
127 0 : int BigitLength() const { return used_digits_ + exponent_; }
128 : Chunk BigitAt(int index) const;
129 : void SubtractTimes(const Bignum& other, int factor);
130 :
131 : Chunk bigits_buffer_[kBigitCapacity];
132 : // A vector backed by bigits_buffer_. This way accesses to the array are
133 : // checked for out-of-bounds errors.
134 : Vector<Chunk> bigits_;
135 : int used_digits_;
136 : // The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize).
137 : int exponent_;
138 :
139 : DISALLOW_COPY_AND_ASSIGN(Bignum);
140 : };
141 :
142 : } // namespace double_conversion
143 :
144 : #endif // DOUBLE_CONVERSION_BIGNUM_H_
|