Qrack  10.0
General classical-emulating-quantum development framework
big_integer.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qimcifa contributors, 2022, 2023. All rights reserved.
4 //
5 // This header has been adapted for OpenCL and C, from big_integer.c by Andre Azevedo.
6 //
7 // Original file:
8 //
9 // big_integer.c
10 // Description: "Arbitrary"-precision integer
11 // Author: Andre Azevedo <http://github.com/andreazevedo>
12 //
13 // The MIT License (MIT)
14 //
15 // Copyright (c) 2014 Andre Azevedo
16 //
17 // Permission is hereby granted, free of charge, to any person obtaining a copy
18 // of this software and associated documentation files (the "Software"), to deal
19 // in the Software without restriction, including without limitation the rights
20 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21 // copies of the Software, and to permit persons to whom the Software is
22 // furnished to do so, subject to the following conditions:
23 //
24 // The above copyright notice and this permission notice shall be included in all
25 // copies or substantial portions of the Software.
26 //
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 // SOFTWARE.
34 
35 #pragma once
36 
37 #include "config.h"
38 
39 #include <cmath>
40 #include <cstddef>
41 #include <cstdint>
42 #include <functional>
43 
44 using std::size_t;
45 
46 #if defined(__SIZEOF_INT128__) && defined(ENABLE_CPP_INT)
47 #define BIG_INTEGER_WORD_BITS 128U
48 #define BIG_INTEGER_WORD_POWER 7U
49 #define BIG_INTEGER_WORD unsigned __int128
50 #define BIG_INTEGER_HALF_WORD uint64_t
51 #define BIG_INTEGER_HALF_WORD_MASK 0xFFFFFFFFFFFFFFFFULL
52 #define BIG_INTEGER_HALF_WORD_MASK_NOT 0xFFFFFFFFFFFFFFFF0000000000000000ULL
53 #else
54 #define BIG_INTEGER_WORD_BITS 64U
55 #define BIG_INTEGER_WORD_POWER 6U
56 #define BIG_INTEGER_WORD uint64_t
57 #define BIG_INTEGER_HALF_WORD uint32_t
58 #define BIG_INTEGER_HALF_WORD_MASK 0xFFFFFFFFULL
59 #define BIG_INTEGER_HALF_WORD_MASK_NOT 0xFFFFFFFF00000000ULL
60 #endif
61 
62 // This can be any power of 2 greater than (or equal to) 64:
63 constexpr size_t BIG_INTEGER_BITS = (1 << QBCAPPOW);
65 
66 // The rest of the constants need to be consistent with the one above:
70 
71 typedef struct BigInteger {
73 
74  inline BigInteger()
75  {
76  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
77  bits[i] = 0U;
78  }
79  }
80 
81  inline BigInteger(const BigInteger& val)
82  {
83  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
84  bits[i] = val.bits[i];
85  }
86  }
87 
88  inline BigInteger(const BIG_INTEGER_WORD& val)
89  {
90  bits[0] = val;
91  for (int i = 1; i < BIG_INTEGER_WORD_SIZE; ++i) {
92  bits[i] = 0U;
93  }
94  }
95 
96 #ifdef __SIZEOF_INT128__
97  inline explicit operator unsigned __int128() const { return (unsigned __int128)bits[0U]; }
98 #endif
99  inline explicit operator uint64_t() const { return (uint64_t)bits[0U]; }
100  inline explicit operator uint32_t() const { return (uint32_t)bits[0U]; }
102 
103 inline void bi_set_0(BigInteger* p)
104 {
105  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
106  p->bits[i] = 0U;
107  }
108 }
109 
110 inline BigInteger bi_copy(const BigInteger& in)
111 {
112  BigInteger result;
113  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
114  result.bits[i] = in.bits[i];
115  }
116  return result;
117 }
118 
119 inline void bi_copy_ip(const BigInteger& in, BigInteger* out)
120 {
121  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
122  out->bits[i] = in.bits[i];
123  }
124 }
125 
126 inline int bi_compare(const BigInteger& left, const BigInteger& right)
127 {
128  for (int i = BIG_INTEGER_MAX_WORD_INDEX; i >= 0; --i) {
129  if (left.bits[i] > right.bits[i]) {
130  return 1;
131  }
132 
133  if (left.bits[i] < right.bits[i]) {
134  return -1;
135  }
136  }
137 
138  return 0;
139 }
140 
141 inline int bi_compare_0(const BigInteger& left)
142 {
143  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
144  if (left.bits[i]) {
145  return 1;
146  }
147  }
148 
149  return 0;
150 }
151 
152 inline int bi_compare_1(const BigInteger& left)
153 {
154  for (int i = BIG_INTEGER_MAX_WORD_INDEX; i > 0; --i) {
155  if (left.bits[i]) {
156  return 1;
157  }
158  }
159 
160  if (left.bits[0] > 1U) {
161  return 1;
162  }
163 
164  if (left.bits[0] < 1U) {
165  return -1;
166  }
167 
168  return 0;
169 }
170 
171 inline BigInteger operator+(const BigInteger& left, const BigInteger& right)
172 {
173  BigInteger result;
174  result.bits[0U] = 0U;
175  for (int i = 0; i < BIG_INTEGER_MAX_WORD_INDEX; ++i) {
176  result.bits[i] += left.bits[i] + right.bits[i];
177  result.bits[i + 1] = (result.bits[i] < left.bits[i]) ? 1 : 0;
178  }
180  return result;
181 }
182 
183 inline void bi_add_ip(BigInteger* left, const BigInteger& right)
184 {
185  for (int i = 0; i < BIG_INTEGER_MAX_WORD_INDEX; ++i) {
186  BIG_INTEGER_WORD temp = left->bits[i];
187  left->bits[i] += right.bits[i];
188  int j = i;
189  while ((j < BIG_INTEGER_MAX_WORD_INDEX) && (left->bits[j] < temp)) {
190  temp = left->bits[++j]++;
191  }
192  }
194 }
195 
196 inline BigInteger operator-(const BigInteger& left, const BigInteger& right)
197 {
198  BigInteger result;
199  result.bits[0U] = 0U;
200  for (int i = 0; i < BIG_INTEGER_MAX_WORD_INDEX; ++i) {
201  result.bits[i] += left.bits[i] - right.bits[i];
202  result.bits[i + 1] = (result.bits[i] > left.bits[i]) ? -1 : 0;
203  }
205  return result;
206 }
207 
208 inline void bi_sub_ip(BigInteger* left, const BigInteger& right)
209 {
210  for (int i = 0; i < BIG_INTEGER_MAX_WORD_INDEX; ++i) {
211  BIG_INTEGER_WORD temp = left->bits[i];
212  left->bits[i] -= right.bits[i];
213  int j = i;
214  while ((j < BIG_INTEGER_MAX_WORD_INDEX) && (left->bits[j] > temp)) {
215  temp = left->bits[++j]--;
216  }
217  }
219 }
220 
221 inline void bi_increment(BigInteger* pBigInt, const BIG_INTEGER_WORD& value)
222 {
223  BIG_INTEGER_WORD temp = pBigInt->bits[0];
224  pBigInt->bits[0] += value;
225 
226  if (temp <= pBigInt->bits[0]) {
227  return;
228  }
229 
230  for (int i = 1; i < BIG_INTEGER_WORD_SIZE; i++) {
231  temp = pBigInt->bits[i]++;
232  if (temp <= pBigInt->bits[i]) {
233  break;
234  }
235  }
236 }
237 
238 inline void bi_decrement(BigInteger* pBigInt, const BIG_INTEGER_WORD& value)
239 {
240  BIG_INTEGER_WORD temp = pBigInt->bits[0];
241  pBigInt->bits[0] -= value;
242 
243  if (temp >= pBigInt->bits[0]) {
244  return;
245  }
246 
247  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; i++) {
248  temp = pBigInt->bits[i]--;
249  if (temp >= pBigInt->bits[i]) {
250  break;
251  }
252  }
253 }
254 
256 {
257  BigInteger result;
258  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
259  result.bits[i] = a[i];
260  }
261 
262  return result;
263 }
264 
265 inline BigInteger bi_lshift_word(const BigInteger& left, BIG_INTEGER_WORD rightMult)
266 {
267  if (!rightMult) {
268  return left;
269  }
270 
271  BigInteger result = 0;
272  for (BIG_INTEGER_WORD i = rightMult; i < BIG_INTEGER_WORD_SIZE; ++i) {
273  result.bits[i] = left.bits[i - rightMult];
274  }
275 
276  return result;
277 }
278 
279 inline void bi_lshift_word_ip(BigInteger* left, BIG_INTEGER_WORD rightMult)
280 {
281  rightMult &= 63U;
282 
283  if (!rightMult) {
284  return;
285  }
286 
287  for (BIG_INTEGER_WORD i = rightMult; i < BIG_INTEGER_WORD_SIZE; ++i) {
288  left->bits[i] = left->bits[i - rightMult];
289  }
290  for (BIG_INTEGER_WORD i = 0U; i < rightMult; ++i) {
291  left->bits[i] = 0U;
292  }
293 }
294 
295 inline BigInteger bi_rshift_word(const BigInteger& left, const BIG_INTEGER_WORD& rightMult)
296 {
297  if (!rightMult) {
298  return left;
299  }
300 
301  BigInteger result = 0U;
302  for (BIG_INTEGER_WORD i = rightMult; i < BIG_INTEGER_WORD_SIZE; ++i) {
303  result.bits[i - rightMult] = left.bits[i];
304  }
305 
306  return result;
307 }
308 
309 inline void bi_rshift_word_ip(BigInteger* left, const BIG_INTEGER_WORD& rightMult)
310 {
311  if (!rightMult) {
312  return;
313  }
314 
315  for (BIG_INTEGER_WORD i = rightMult; i < BIG_INTEGER_WORD_SIZE; ++i) {
316  left->bits[i - rightMult] = left->bits[i];
317  }
318  for (BIG_INTEGER_WORD i = 0U; i < rightMult; ++i) {
319  left->bits[BIG_INTEGER_MAX_WORD_INDEX - i] = 0U;
320  }
321 }
322 
324 {
325  const BIG_INTEGER_WORD rShift64 = right >> BIG_INTEGER_WORD_POWER;
326  const BIG_INTEGER_WORD rMod = right - (rShift64 << BIG_INTEGER_WORD_POWER);
327 
328  BigInteger result = bi_lshift_word(left, rShift64);
329 
330  if (!rMod) {
331  return result;
332  }
333 
334  const BIG_INTEGER_WORD rModComp = BIG_INTEGER_WORD_BITS - rMod;
335  BIG_INTEGER_WORD carry = 0U;
336  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
337  right = result.bits[i];
338  result.bits[i] = carry | (right << rMod);
339  carry = right >> rModComp;
340  }
341 
342  return result;
343 }
344 
345 inline void bi_lshift_ip(BigInteger* left, BIG_INTEGER_WORD right)
346 {
347  const BIG_INTEGER_WORD rShift64 = right >> BIG_INTEGER_WORD_POWER;
348  const BIG_INTEGER_WORD rMod = right - (rShift64 << BIG_INTEGER_WORD_POWER);
349 
350  bi_lshift_word_ip(left, rShift64);
351 
352  if (!rMod) {
353  return;
354  }
355 
356  const BIG_INTEGER_WORD rModComp = BIG_INTEGER_WORD_BITS - rMod;
357  BIG_INTEGER_WORD carry = 0U;
358  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
359  right = left->bits[i];
360  left->bits[i] = carry | (right << rMod);
361  carry = right >> rModComp;
362  }
363 }
364 
366 {
367  const BIG_INTEGER_WORD rShift64 = right >> BIG_INTEGER_WORD_POWER;
368  const BIG_INTEGER_WORD rMod = right - (rShift64 << BIG_INTEGER_WORD_POWER);
369 
370  BigInteger result = bi_rshift_word(left, rShift64);
371 
372  if (!rMod) {
373  return result;
374  }
375 
376  const BIG_INTEGER_WORD rModComp = BIG_INTEGER_WORD_BITS - rMod;
377  BIG_INTEGER_WORD carry = 0U;
378  for (int i = BIG_INTEGER_MAX_WORD_INDEX; i >= 0; --i) {
379  right = result.bits[i];
380  result.bits[i] = carry | (right >> rMod);
381  carry = right << rModComp;
382  }
383 
384  return result;
385 }
386 
387 inline void bi_rshift_ip(BigInteger* left, BIG_INTEGER_WORD right)
388 {
389  const BIG_INTEGER_WORD rShift64 = right >> BIG_INTEGER_WORD_POWER;
390  const BIG_INTEGER_WORD rMod = right - (rShift64 << BIG_INTEGER_WORD_POWER);
391 
392  bi_rshift_word_ip(left, rShift64);
393 
394  if (!rMod) {
395  return;
396  }
397 
398  const BIG_INTEGER_WORD rModComp = BIG_INTEGER_WORD_BITS - rMod;
399  BIG_INTEGER_WORD carry = 0U;
400  for (int i = BIG_INTEGER_MAX_WORD_INDEX; i >= 0; --i) {
401  right = left->bits[i];
402  left->bits[i] = carry | (right >> rMod);
403  carry = right << rModComp;
404  }
405 }
406 
407 inline int bi_log2(const BigInteger& n)
408 {
409  int pw = 0;
410  BigInteger p = n >> 1U;
411  while (bi_compare_0(p) != 0) {
412  bi_rshift_ip(&p, 1U);
413  ++pw;
414  }
415  return pw;
416 }
417 
418 inline int bi_and_1(const BigInteger& left) { return left.bits[0] & 1; }
419 
420 inline BigInteger operator&(const BigInteger& left, const BigInteger& right)
421 {
422  BigInteger result;
423  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
424  result.bits[i] = left.bits[i] & right.bits[i];
425  }
426  return result;
427 }
428 
429 inline void bi_and_ip(BigInteger* left, const BigInteger& right)
430 {
431  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
432  left->bits[i] &= right.bits[i];
433  }
434 }
435 
436 inline BigInteger operator|(const BigInteger& left, const BigInteger& right)
437 {
438  BigInteger result;
439  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
440  result.bits[i] = left.bits[i] | right.bits[i];
441  }
442  return result;
443 }
444 
445 inline void bi_or_ip(BigInteger* left, const BigInteger& right)
446 {
447  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
448  left->bits[i] |= right.bits[i];
449  }
450 }
451 
452 inline BigInteger operator^(const BigInteger& left, const BigInteger& right)
453 {
454  BigInteger result;
455  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
456  result.bits[i] = left.bits[i] ^ right.bits[i];
457  }
458  return result;
459 }
460 
461 inline void bi_xor_ip(BigInteger* left, const BigInteger& right)
462 {
463  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
464  left->bits[i] ^= right.bits[i];
465  }
466 }
467 
468 inline BigInteger operator~(const BigInteger& left)
469 {
470  BigInteger result;
471  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
472  result.bits[i] = ~(left.bits[i]);
473  }
474  return result;
475 }
476 
477 inline void bi_not_ip(BigInteger* left)
478 {
479  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
480  left->bits[i] = ~(left->bits[i]);
481  }
482 }
483 
484 inline double bi_to_double(const BigInteger& in)
485 {
486  double toRet = 0.0;
487  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
488  if (in.bits[i]) {
489  toRet += in.bits[i] * pow(2.0, BIG_INTEGER_WORD_BITS * i);
490  }
491  }
492  return toRet;
493 }
494 
495 inline bool operator==(const BigInteger& left, const BigInteger& right) { return bi_compare(left, right) == 0; }
496 inline bool operator<(const BigInteger& left, const BigInteger& right) { return bi_compare(left, right) < 0; }
497 inline bool operator<=(const BigInteger& left, const BigInteger& right) { return bi_compare(left, right) <= 0; }
498 inline bool operator>(const BigInteger& left, const BigInteger& right) { return bi_compare(left, right) > 0; }
499 inline bool operator>=(const BigInteger& left, const BigInteger& right) { return bi_compare(left, right) >= 0; }
500 inline bool operator!=(const BigInteger& left, const BigInteger& right) { return bi_compare(left, right) != 0; }
501 
503 {
504  bi_increment(&a, 1U);
505  return a;
506 }
507 
509 {
510  bi_decrement(&a, 1U);
511  return a;
512 }
513 
519 
520 #if true
525 BigInteger operator*(const BigInteger& left, const BigInteger& right);
526 #else
531 BigInteger operator*(const BigInteger& left, const BigInteger& right);
532 #endif
533 
538 void bi_div_mod_small(
539  const BigInteger& left, BIG_INTEGER_HALF_WORD right, BigInteger* quotient, BIG_INTEGER_HALF_WORD* rmndr);
540 
545 void bi_div_mod(const BigInteger& left, const BigInteger& right, BigInteger* quotient, BigInteger* rmndr);
546 
547 // Hashing provided by (Anthropic) Claude
549  size_t operator()(const BigInteger& bi) const noexcept
550  {
551  // Murmur-inspired word combination
552  // Fast, good distribution, no external dependencies
553  size_t seed = BIG_INTEGER_WORD_SIZE;
554  for (int i = 0; i < BIG_INTEGER_WORD_SIZE; ++i) {
555  // Mix the lower 64 bits of each word
556  size_t word = static_cast<size_t>(bi.bits[i]);
557  word = (~word) + (word << 21);
558  word ^= word >> 24;
559  word += (word << 3) + (word << 8);
560  word ^= word >> 14;
561  word += (word << 2) + (word << 4);
562  word ^= word >> 28;
563  word += word << 31;
564  seed ^= word + 0x9e3779b9 + (seed << 6) + (seed >> 2);
565  }
566  return seed;
567  }
568 };
569 
572 BigInteger operator/(const BigInteger& left, const BigInteger& right);
573 BigInteger operator%(const BigInteger& left, const BigInteger& right);
574 
575 // Hash injection provided by (Anthropic) Claude
576 namespace std {
577 template <> struct hash<BigInteger> {
578  size_t operator()(const BigInteger& bi) const noexcept { return BigIntegerHash{}(bi); }
579 };
580 } // namespace std
BigInteger operator~(const BigInteger &left)
Definition: big_integer.hpp:468
void bi_or_ip(BigInteger *left, const BigInteger &right)
Definition: big_integer.hpp:445
BigInteger operator/(const BigInteger &left, BIG_INTEGER_HALF_WORD right)
Definition: big_integer.cpp:328
constexpr size_t BIG_INTEGER_BITS
Definition: big_integer.hpp:63
constexpr size_t BIG_INTEGER_HALF_WORD_BITS
Definition: big_integer.hpp:67
BigInteger operator--(BigInteger &a)
Definition: big_integer.hpp:508
void bi_decrement(BigInteger *pBigInt, const BIG_INTEGER_WORD &value)
Definition: big_integer.hpp:238
BigInteger operator&(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:420
BigInteger operator>>(const BigInteger &left, BIG_INTEGER_WORD right)
Definition: big_integer.hpp:365
void bi_increment(BigInteger *pBigInt, const BIG_INTEGER_WORD &value)
Definition: big_integer.hpp:221
void bi_div_mod_small(const BigInteger &left, BIG_INTEGER_HALF_WORD right, BigInteger *quotient, BIG_INTEGER_HALF_WORD *rmndr)
"Schoolbook division" (on half words) Complexity - O(x^2)
Definition: big_integer.cpp:184
#define BIG_INTEGER_WORD_POWER
Definition: big_integer.hpp:55
constexpr int BIG_INTEGER_MAX_WORD_INDEX
Definition: big_integer.hpp:69
int bi_and_1(const BigInteger &left)
Definition: big_integer.hpp:418
bool operator>=(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:499
BigInteger operator|(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:436
BigInteger operator+(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:171
void bi_add_ip(BigInteger *left, const BigInteger &right)
Definition: big_integer.hpp:183
bool operator>(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:498
BigInteger bi_rshift_word(const BigInteger &left, const BIG_INTEGER_WORD &rightMult)
Definition: big_integer.hpp:295
BigInteger operator^(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:452
int bi_compare_0(const BigInteger &left)
Definition: big_integer.hpp:141
bool operator!=(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:500
BigInteger bi_lshift_word(const BigInteger &left, BIG_INTEGER_WORD rightMult)
Definition: big_integer.hpp:265
int bi_compare(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:126
BIG_INTEGER_HALF_WORD operator%(const BigInteger &left, BIG_INTEGER_HALF_WORD right)
Definition: big_integer.cpp:337
void bi_and_ip(BigInteger *left, const BigInteger &right)
Definition: big_integer.hpp:429
constexpr int BIG_INTEGER_WORD_SIZE
Definition: big_integer.hpp:64
BigInteger operator<<(const BigInteger &left, BIG_INTEGER_WORD right)
Definition: big_integer.hpp:323
#define BIG_INTEGER_WORD_BITS
Definition: big_integer.hpp:54
#define BIG_INTEGER_WORD
Definition: big_integer.hpp:56
void bi_lshift_word_ip(BigInteger *left, BIG_INTEGER_WORD rightMult)
Definition: big_integer.hpp:279
bool operator==(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:495
double bi_to_double(const BigInteger &in)
Definition: big_integer.hpp:484
void bi_copy_ip(const BigInteger &in, BigInteger *out)
Definition: big_integer.hpp:119
BigInteger bi_copy(const BigInteger &in)
Definition: big_integer.hpp:110
void bi_rshift_word_ip(BigInteger *left, const BIG_INTEGER_WORD &rightMult)
Definition: big_integer.hpp:309
void bi_not_ip(BigInteger *left)
Definition: big_integer.hpp:477
int bi_compare_1(const BigInteger &left)
Definition: big_integer.hpp:152
bool operator<(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:496
void bi_set_0(BigInteger *p)
Definition: big_integer.hpp:103
void bi_xor_ip(BigInteger *left, const BigInteger &right)
Definition: big_integer.hpp:461
void bi_sub_ip(BigInteger *left, const BigInteger &right)
Definition: big_integer.hpp:208
BigInteger operator*(const BigInteger &left, BIG_INTEGER_HALF_WORD right)
"Schoolbook multiplication" (on half words) Complexity - O(x^2)
Definition: big_integer.cpp:41
int bi_log2(const BigInteger &n)
Definition: big_integer.hpp:407
constexpr int BIG_INTEGER_HALF_WORD_SIZE
Definition: big_integer.hpp:68
void bi_div_mod(const BigInteger &left, const BigInteger &right, BigInteger *quotient, BigInteger *rmndr)
Adapted from Qrack! (The fundamental algorithm was discovered before.) Complexity - O(log)
Definition: big_integer.cpp:227
BigInteger bi_load(BIG_INTEGER_WORD *a)
Definition: big_integer.hpp:255
void bi_lshift_ip(BigInteger *left, BIG_INTEGER_WORD right)
Definition: big_integer.hpp:345
bool operator<=(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:497
#define BIG_INTEGER_HALF_WORD
Definition: big_integer.hpp:57
struct BigInteger BigInteger
BigInteger operator-(const BigInteger &left, const BigInteger &right)
Definition: big_integer.hpp:196
void bi_rshift_ip(BigInteger *left, BIG_INTEGER_WORD right)
Definition: big_integer.hpp:387
BigInteger operator++(BigInteger &a)
Definition: big_integer.hpp:502
half pow(half x, half y)
Power function.
Definition: half.hpp:3721
Extensions to the C++ standard library.
Definition: big_integer.hpp:576
MICROSOFT_QUANTUM_DECL void U(_In_ uintq sid, _In_ uintq q, _In_ double theta, _In_ double phi, _In_ double lambda)
(External API) 3-parameter unitary gate
Definition: pinvoke_api.cpp:1728
MICROSOFT_QUANTUM_DECL void seed(_In_ uintq sid, _In_ uintq s)
(External API) Set RNG seed for simulator ID
Definition: pinvoke_api.cpp:1063
Definition: big_integer.hpp:548
size_t operator()(const BigInteger &bi) const noexcept
Definition: big_integer.hpp:549
Definition: big_integer.hpp:71
BigInteger(const BIG_INTEGER_WORD &val)
Definition: big_integer.hpp:88
BIG_INTEGER_WORD bits[BIG_INTEGER_WORD_SIZE]
Definition: big_integer.hpp:72
BigInteger()
Definition: big_integer.hpp:74
BigInteger(const BigInteger &val)
Definition: big_integer.hpp:81
size_t operator()(const BigInteger &bi) const noexcept
Definition: big_integer.hpp:578