OLD | NEW |
| (Empty) |
1 // Copyright 2012 Google Inc. All Rights Reserved. | |
2 | |
3 #ifndef VM_BIGINT_OPERATIONS_H_ | |
4 #define VM_BIGINT_OPERATIONS_H_ | |
5 | |
6 #include "platform/utils.h" | |
7 | |
8 #include "vm/object.h" | |
9 | |
10 namespace dart { | |
11 | |
12 class BigintOperations : public AllStatic { | |
13 public: | |
14 static RawBigint* NewFromSmi(const Smi& smi, Heap::Space space = Heap::kNew); | |
15 static RawBigint* NewFromInt64(int64_t value, Heap::Space space = Heap::kNew); | |
16 static RawBigint* NewFromUint64(uint64_t value, | |
17 Heap::Space space = Heap::kNew); | |
18 // The given string must be a valid integer representation. It may be | |
19 // prefixed by a minus and/or "0x". | |
20 // Returns Bigint::null() if the string cannot be parsed. | |
21 static RawBigint* NewFromCString(const char* str, | |
22 Heap::Space space = Heap::kNew); | |
23 static RawBigint* NewFromDouble(double d, Heap::Space space = Heap::kNew); | |
24 | |
25 // Compute chunk length of the bigint instance created for the | |
26 // specified hex string. The specified hex string must be a | |
27 // nul-terminated string of hex-digits. It must only contain | |
28 // hex-digits. Leading "0x" is not allowed. | |
29 static intptr_t ComputeChunkLength(const char* hex_string); | |
30 | |
31 // Create a bigint instance from the specified hex string. The given string | |
32 // must be a nul-terminated string of hex-digits. It must only contain | |
33 // hex-digits. Leading "0x" is not allowed. | |
34 static RawBigint* FromHexCString(const char* hex_string, | |
35 Heap::Space space = Heap::kNew); | |
36 | |
37 // Helper method to initialize a bigint instance object with the bigint value | |
38 // in the specified string. The given string must be a nul-terminated string | |
39 // of hex-digits. It must only contain hex-digits, leading "0x" is not | |
40 // allowed. | |
41 static void FromHexCString(const char* hex_string, const Bigint& value); | |
42 | |
43 // The given string must be a nul-terminated string of decimal digits. It | |
44 // must only contain decimal digits (0-9). No sign is allowed. Leading | |
45 // zeroes are ignored. | |
46 static RawBigint* FromDecimalCString(const char* str, | |
47 Heap::Space space = Heap::kNew); | |
48 | |
49 // Converts the bigint to a HEX string. The returned string is prepended by | |
50 // a "0x" (after the optional minus-sign). | |
51 static const char* ToHexCString(intptr_t length, | |
52 bool is_negative, | |
53 void* data, | |
54 uword (*allocator)(intptr_t size)); | |
55 | |
56 static const char* ToHexCString(const Bigint& bigint, | |
57 uword (*allocator)(intptr_t size)); | |
58 | |
59 static const char* ToDecimalCString(const Bigint& bigint, | |
60 uword (*allocator)(intptr_t size)); | |
61 | |
62 static bool FitsIntoSmi(const Bigint& bigint); | |
63 static RawSmi* ToSmi(const Bigint& bigint); | |
64 | |
65 static bool FitsIntoInt64(const Bigint& bigint); | |
66 static int64_t ToInt64(const Bigint& bigint); | |
67 | |
68 static bool FitsIntoUint64(const Bigint& bigint); | |
69 static bool AbsFitsIntoUint64(const Bigint& bigint); | |
70 static uint64_t ToUint64(const Bigint& bigint); | |
71 static uint32_t TruncateToUint32(const Bigint& bigint); | |
72 static uint64_t AbsToUint64(const Bigint& bigint); | |
73 | |
74 static RawDouble* ToDouble(const Bigint& bigint); | |
75 | |
76 static RawBigint* Add(const Bigint& a, const Bigint& b) { | |
77 bool negate_b = false; | |
78 return AddSubtract(a, b, negate_b); | |
79 } | |
80 static RawBigint* Subtract(const Bigint& a, const Bigint& b) { | |
81 bool negate_b = true; | |
82 return AddSubtract(a, b, negate_b); | |
83 } | |
84 static RawBigint* Multiply(const Bigint& a, const Bigint& b); | |
85 // TODO(floitsch): what to do for divisions by zero. | |
86 static RawBigint* Divide(const Bigint& a, const Bigint& b); | |
87 static RawBigint* Modulo(const Bigint& a, const Bigint& b); | |
88 static RawBigint* Remainder(const Bigint& a, const Bigint& b); | |
89 | |
90 static RawBigint* ShiftLeft(const Bigint& bigint, intptr_t amount); | |
91 static RawBigint* ShiftRight(const Bigint& bigint, intptr_t amount); | |
92 static RawBigint* BitAnd(const Bigint& a, const Bigint& b); | |
93 static RawBigint* BitOr(const Bigint& a, const Bigint& b); | |
94 static RawBigint* BitXor(const Bigint& a, const Bigint& b); | |
95 static RawBigint* BitNot(const Bigint& bigint); | |
96 static int64_t BitLength(const Bigint& bigint); | |
97 | |
98 static int Compare(const Bigint& a, const Bigint& b); | |
99 | |
100 static bool IsClamped(const Bigint& bigint) { | |
101 intptr_t length = bigint.Length(); | |
102 return (length == 0) || (bigint.GetChunkAt(length - 1) != 0); | |
103 } | |
104 | |
105 private: | |
106 typedef Bigint::Chunk Chunk; | |
107 typedef Bigint::DoubleChunk DoubleChunk; | |
108 | |
109 static const int kDigitBitSize = 28; | |
110 static const Chunk kDigitMask = (static_cast<Chunk>(1) << kDigitBitSize) - 1; | |
111 static const Chunk kDigitMaxValue = kDigitMask; | |
112 static const int kChunkSize = sizeof(Chunk); | |
113 static const int kChunkBitSize = kChunkSize * kBitsPerByte; | |
114 static const int kHexCharsPerDigit = kDigitBitSize / 4; | |
115 | |
116 static RawBigint* Zero() { return Bigint::Allocate(0); } | |
117 static RawBigint* One() { | |
118 Bigint& result = Bigint::Handle(Bigint::Allocate(1)); | |
119 result.SetChunkAt(0, 1); | |
120 return result.raw(); | |
121 } | |
122 static RawBigint* MinusOne() { | |
123 Bigint& result = Bigint::Handle(One()); | |
124 result.ToggleSign(); | |
125 return result.raw(); | |
126 } | |
127 | |
128 // Performs an addition or subtraction depending on the negate_b argument. | |
129 static RawBigint* AddSubtract(const Bigint& a, | |
130 const Bigint& b, | |
131 bool negate_b); | |
132 | |
133 static int UnsignedCompare(const Bigint& a, const Bigint& b); | |
134 static int UnsignedCompareNonClamped(const Bigint& a, const Bigint& b); | |
135 static RawBigint* UnsignedAdd(const Bigint& a, const Bigint& b); | |
136 static RawBigint* UnsignedSubtract(const Bigint& a, const Bigint& b); | |
137 | |
138 static RawBigint* MultiplyWithDigit(const Bigint& bigint, Chunk digit); | |
139 static RawBigint* DigitsShiftLeft(const Bigint& bigint, intptr_t amount) { | |
140 return ShiftLeft(bigint, amount * kDigitBitSize); | |
141 } | |
142 static void DivideRemainder(const Bigint& a, const Bigint& b, | |
143 Bigint* quotient, Bigint* remainder); | |
144 static Chunk InplaceUnsignedDivideRemainderDigit( | |
145 const Bigint& dividend_quotient, Chunk divisor_digit); | |
146 | |
147 // Removes leading zero-chunks by adjusting the bigint's length. | |
148 static void Clamp(const Bigint& bigint); | |
149 | |
150 static RawBigint* Copy(const Bigint& bigint); | |
151 | |
152 static intptr_t CountBits(Chunk digit); | |
153 | |
154 DISALLOW_IMPLICIT_CONSTRUCTORS(BigintOperations); | |
155 }; | |
156 | |
157 } // namespace dart | |
158 | |
159 #endif // VM_BIGINT_OPERATIONS_H_ | |
OLD | NEW |