dconv 2.0
C++14 library for printing and parsing floating point numbers
Loading...
Searching...
No Matches
bigint.hpp
Go to the documentation of this file.
1
25#ifndef __EISELLEMIREPOWGEN_BIGINT_HPP__
26#define __EISELLEMIREPOWGEN_BIGINT_HPP__
27
28#include <vector>
29
30#include <cstdint>
31#include <cstddef>
32
33struct Power
34{
35 uint64_t hi;
36 uint64_t lo;
37};
38
39class BigInt
40{
41public:
42 explicit BigInt (uint64_t value = 0)
43 {
44 if (value == 0)
45 {
46 data.push_back (0);
47 }
48 else
49 {
50 data.push_back (static_cast<uint32_t> (value));
51 uint32_t high = static_cast<uint32_t> (value >> 32);
52 if (high != 0)
53 {
54 data.push_back (high);
55 }
56 }
57 }
58
59 void multiply (uint32_t factor)
60 {
61 uint64_t carry = 0;
62 for (size_t i = 0; i < data.size (); ++i)
63 {
64 uint64_t product = static_cast<uint64_t> (data[i]) * factor + carry;
65 data[i] = static_cast<uint32_t> (product);
66 carry = product >> 32;
67 }
68 if (carry != 0)
69 {
70 data.push_back (static_cast<uint32_t> (carry));
71 }
72 }
73
74 void divide (uint32_t divisor)
75 {
76 uint64_t remainder = 0;
77 for (int i = static_cast<int> (data.size ()) - 1; i >= 0; --i)
78 {
79 uint64_t current = (remainder << 32) | data[i];
80 data[i] = static_cast<uint32_t> (current / divisor);
81 remainder = current % divisor;
82 }
83 removeLeadingZeros ();
84 }
85
86 void shiftLeft (int shift)
87 {
88 if (shift == 0)
89 return;
90
91 int blockShift = shift / 32;
92 int bitShift = shift % 32;
93
94 if (blockShift > 0)
95 {
96 data.insert (data.begin (), blockShift, 0);
97 }
98
99 if (bitShift > 0)
100 {
101 uint32_t carry = 0;
102 for (size_t i = blockShift; i < data.size (); ++i)
103 {
104 uint64_t temp = (static_cast<uint64_t> (data[i]) << bitShift) | carry;
105 data[i] = static_cast<uint32_t> (temp);
106 carry = static_cast<uint32_t> (temp >> 32);
107 }
108 if (carry != 0)
109 {
110 data.push_back (carry);
111 }
112 }
113 }
114
115 static BigInt powerOfTwo (int shift)
116 {
117 BigInt result;
118 result.data.clear ();
119
120 int chunks = shift / 32;
121 int bit = shift % 32;
122
123 result.data.resize (chunks, 0);
124 result.data.push_back (1U << bit);
125
126 return result;
127 }
128
129 int bitLength () const
130 {
131 int length = static_cast<int> (data.size ()) * 32;
132 uint32_t top = data.back ();
133 while (length > 0 && (top & 0x80000000) == 0)
134 {
135 top <<= 1;
136 --length;
137 }
138 return length;
139 }
140
142 {
143 if (data.empty () || (data.size () == 1 && data[0] == 0))
144 {
145 return {0, 0};
146 }
147
148 int msbBlock = static_cast<int> (data.size ()) - 1;
149 uint32_t msbValue = data[msbBlock];
150
151 int msbBit = 31;
152 while (msbBit > 0 && ((msbValue >> msbBit) & 1) == 0)
153 {
154 --msbBit;
155 }
156
157 int startBit = msbBlock * 32 + msbBit;
158
159 uint64_t hi = 0;
160 uint64_t lo = 0;
161
162 for (int i = 0; i < 64; ++i)
163 {
164 int bitPos = startBit - i;
165 if (bitPos >= 0)
166 {
167 int block = bitPos / 32;
168 if (block < static_cast<int> (data.size ()))
169 {
170 int bit = bitPos % 32;
171 uint64_t bitValue = (data[block] >> bit) & 1;
172 hi |= (bitValue << (63 - i));
173 }
174 }
175 }
176
177 for (int i = 0; i < 64; ++i)
178 {
179 int bitPos = startBit - 64 - i;
180 if (bitPos >= 0)
181 {
182 int block = bitPos / 32;
183 if (block < static_cast<int> (data.size ()))
184 {
185 int bit = bitPos % 32;
186 uint64_t bitValue = (data[block] >> bit) & 1;
187 lo |= (bitValue << (63 - i));
188 }
189 }
190 }
191
192 return {hi, lo};
193 }
194
195private:
196 void removeLeadingZeros ()
197 {
198 while (data.size () > 1 && data.back () == 0)
199 {
200 data.pop_back ();
201 }
202 }
203
204 std::vector<uint32_t> data;
205};
206
207#endif
Definition bigint.hpp:40
void shiftLeft(int shift)
Definition bigint.hpp:86
void divide(uint32_t divisor)
Definition bigint.hpp:74
Power getTop128() const
Definition bigint.hpp:141
static BigInt powerOfTwo(int shift)
Definition bigint.hpp:115
void multiply(uint32_t factor)
Definition bigint.hpp:59
int bitLength() const
Definition bigint.hpp:129
BigInt(uint64_t value=0)
Definition bigint.hpp:42
Definition bigint.hpp:34
uint64_t hi
Definition bigint.hpp:35
uint64_t lo
Definition bigint.hpp:36