dconv 1.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 __POWGEN_BIGINT_HPP__
26#define __POWGEN_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) return;
89
90 int blockShift = shift / 32;
91 int bitShift = shift % 32;
92
93 if (blockShift > 0)
94 {
95 data.insert (data.begin (), blockShift, 0);
96 }
97
98 if (bitShift > 0)
99 {
100 uint32_t carry = 0;
101 for (size_t i = blockShift; i < data.size (); ++i)
102 {
103 uint64_t temp = (static_cast <uint64_t> (data[i]) << bitShift) | carry;
104 data[i] = static_cast <uint32_t> (temp);
105 carry = static_cast <uint32_t> (temp >> 32);
106 }
107 if (carry != 0)
108 {
109 data.push_back (carry);
110 }
111 }
112 }
113
114 static BigInt powerOfTwo (int shift)
115 {
116 BigInt result;
117 result.data.clear ();
118
119 int chunks = shift / 32;
120 int bit = shift % 32;
121
122 result.data.resize (chunks, 0);
123 result.data.push_back (1U << bit);
124
125 return result;
126 }
127
129 {
130 if (data.empty () || (data.size () == 1 && data[0] == 0))
131 {
132 return {0, 0};
133 }
134
135 int msbBlock = static_cast <int> (data.size ()) - 1;
136 uint32_t msbValue = data[msbBlock];
137
138 int msbBit = 31;
139 while (msbBit > 0 && ((msbValue >> msbBit) & 1) == 0)
140 {
141 --msbBit;
142 }
143
144 int startBit = msbBlock * 32 + msbBit;
145
146 uint64_t hi = 0;
147 uint64_t lo = 0;
148
149 for (int i = 0; i < 64; ++i)
150 {
151 int bitPos = startBit - i;
152 if (bitPos >= 0)
153 {
154 int block = bitPos / 32;
155 if (block < static_cast <int> (data.size ()))
156 {
157 int bit = bitPos % 32;
158 uint64_t bitValue = (data[block] >> bit) & 1;
159 hi |= (bitValue << (63 - i));
160 }
161 }
162 }
163
164 for (int i = 0; i < 64; ++i)
165 {
166 int bitPos = startBit - 64 - i;
167 if (bitPos >= 0)
168 {
169 int block = bitPos / 32;
170 if (block < static_cast <int> (data.size ()))
171 {
172 int bit = bitPos % 32;
173 uint64_t bitValue = (data[block] >> bit) & 1;
174 lo |= (bitValue << (63 - i));
175 }
176 }
177 }
178
179 return {hi, lo};
180 }
181
182private:
183 void removeLeadingZeros ()
184 {
185 while (data.size () > 1 && data.back () == 0)
186 {
187 data.pop_back ();
188 }
189 }
190
191 std::vector <uint32_t> data;
192};
193
194#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:128
static BigInt powerOfTwo(int shift)
Definition bigint.hpp:114
void multiply(uint32_t factor)
Definition bigint.hpp:59
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