LMMS
Loading...
Searching...
No Matches
juce_BigInteger.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26namespace
27{
28 inline uint32 bitToMask (const int bit) noexcept { return (uint32) 1 << (bit & 31); }
29 inline size_t bitToIndex (const int bit) noexcept { return (size_t) (bit >> 5); }
30 inline size_t sizeNeededToHold (int highestBit) noexcept { return (size_t) (highestBit >> 5) + 1; }
31}
32
34{
35 jassert (n != 0); // (the built-in functions may not work for n = 0)
36
37 #if JUCE_GCC || JUCE_CLANG
38 return 31 - __builtin_clz (n);
39 #elif JUCE_MSVC
40 unsigned long highest;
41 _BitScanReverse (&highest, n);
42 return (int) highest;
43 #else
44 n |= (n >> 1);
45 n |= (n >> 2);
46 n |= (n >> 4);
47 n |= (n >> 8);
48 n |= (n >> 16);
49 return countNumberOfBits (n >> 1);
50 #endif
51}
52
53//==============================================================================
60
63 highestBit (31),
64 negative (value < 0)
65{
66 preallocated[0] = (uint32) std::abs (value);
67
68 for (int i = 1; i < numPreallocatedInts; ++i)
69 preallocated[i] = 0;
70
72}
73
76 highestBit (31)
77{
79
80 for (int i = 1; i < numPreallocatedInts; ++i)
81 preallocated[i] = 0;
82
84}
85
88 highestBit (63),
89 negative (value < 0)
90{
91 if (value < 0)
92 value = -value;
93
95 preallocated[1] = (uint32) (value >> 32);
96
97 for (int i = 2; i < numPreallocatedInts; ++i)
98 preallocated[i] = 0;
99
101}
102
105 highestBit (other.getHighestBit()),
106 negative (other.negative)
107{
110
111 memcpy (getValues(), other.getValues(), sizeof (uint32) * allocatedSize);
112}
113
115 : heapAllocation (std::move (other.heapAllocation)),
116 allocatedSize (other.allocatedSize),
117 highestBit (other.highestBit),
118 negative (other.negative)
119{
120 memcpy (preallocated, other.preallocated, sizeof (preallocated));
121}
122
123BigInteger& BigInteger::operator= (BigInteger&& other) noexcept
124{
125 heapAllocation = std::move (other.heapAllocation);
126 memcpy (preallocated, other.preallocated, sizeof (preallocated));
127 allocatedSize = other.allocatedSize;
128 highestBit = other.highestBit;
129 negative = other.negative;
130 return *this;
131}
132
133void BigInteger::swapWith (BigInteger& other) noexcept
134{
135 for (int i = 0; i < numPreallocatedInts; ++i)
136 std::swap (preallocated[i], other.preallocated[i]);
137
138 heapAllocation.swapWith (other.heapAllocation);
139 std::swap (allocatedSize, other.allocatedSize);
140 std::swap (highestBit, other.highestBit);
141 std::swap (negative, other.negative);
142}
143
144BigInteger& BigInteger::operator= (const BigInteger& other)
145{
146 if (this != &other)
147 {
148 highestBit = other.getHighestBit();
149 auto newAllocatedSize = (size_t) jmax ((size_t) numPreallocatedInts, sizeNeededToHold (highestBit));
150
151 if (newAllocatedSize <= numPreallocatedInts)
152 heapAllocation.free();
153 else if (newAllocatedSize != allocatedSize)
154 heapAllocation.malloc (newAllocatedSize);
155
156 allocatedSize = newAllocatedSize;
157
158 memcpy (getValues(), other.getValues(), sizeof (uint32) * allocatedSize);
159 negative = other.negative;
160 }
161
162 return *this;
163}
164
166{
168
169 return heapAllocation != nullptr ? heapAllocation
170 : const_cast<uint32*> (preallocated);
171}
172
173uint32* BigInteger::ensureSize (const size_t numVals)
174{
175 if (numVals > allocatedSize)
176 {
177 auto oldSize = allocatedSize;
178 allocatedSize = ((numVals + 2) * 3) / 2;
179
180 if (heapAllocation == nullptr)
181 {
184 }
185 else
186 {
188
189 for (auto* values = getValues(); oldSize < allocatedSize; ++oldSize)
190 values[oldSize] = 0;
191 }
192 }
193
194 return getValues();
195}
196
197//==============================================================================
198bool BigInteger::operator[] (const int bit) const noexcept
199{
200 return bit <= highestBit && bit >= 0
201 && ((getValues() [bitToIndex (bit)] & bitToMask (bit)) != 0);
202}
203
205{
206 auto n = (int) (getValues()[0] & 0x7fffffff);
207 return negative ? -n : n;
208}
209
211{
212 auto* values = getValues();
213 auto n = (((int64) (values[1] & 0x7fffffff)) << 32) | values[0];
214 return negative ? -n : n;
215}
216
217BigInteger BigInteger::getBitRange (int startBit, int numBits) const
218{
220 numBits = jmax (0, jmin (numBits, getHighestBit() + 1 - startBit));
221 auto* destValues = r.ensureSize (sizeNeededToHold (numBits));
222 r.highestBit = numBits;
223
224 for (int i = 0; numBits > 0;)
225 {
226 destValues[i++] = getBitRangeAsInt (startBit, (int) jmin (32, numBits));
227 numBits -= 32;
228 startBit += 32;
229 }
230
231 r.highestBit = r.getHighestBit();
232 return r;
233}
234
235uint32 BigInteger::getBitRangeAsInt (const int startBit, int numBits) const noexcept
236{
237 if (numBits > 32)
238 {
239 jassertfalse; // use getBitRange() if you need more than 32 bits..
240 numBits = 32;
241 }
242
243 numBits = jmin (numBits, highestBit + 1 - startBit);
244
245 if (numBits <= 0)
246 return 0;
247
248 auto pos = bitToIndex (startBit);
249 auto offset = startBit & 31;
250 auto endSpace = 32 - numBits;
251 auto* values = getValues();
252
253 auto n = ((uint32) values [pos]) >> offset;
254
255 if (offset > endSpace)
256 n |= ((uint32) values [pos + 1]) << (32 - offset);
257
258 return n & (((uint32) 0xffffffff) >> endSpace);
259}
260
261void BigInteger::setBitRangeAsInt (const int startBit, int numBits, uint32 valueToSet)
262{
263 if (numBits > 32)
264 {
266 numBits = 32;
267 }
268
269 for (int i = 0; i < numBits; ++i)
270 {
271 setBit (startBit + i, (valueToSet & 1) != 0);
272 valueToSet >>= 1;
273 }
274}
275
276//==============================================================================
278{
279 heapAllocation.free();
281 highestBit = -1;
282 negative = false;
283
284 for (int i = 0; i < numPreallocatedInts; ++i)
285 preallocated[i] = 0;
286}
287
288void BigInteger::setBit (const int bit)
289{
290 if (bit >= 0)
291 {
292 if (bit > highestBit)
293 {
294 ensureSize (sizeNeededToHold (bit));
295 highestBit = bit;
296 }
297
298 getValues() [bitToIndex (bit)] |= bitToMask (bit);
299 }
300}
301
302void BigInteger::setBit (const int bit, const bool shouldBeSet)
303{
304 if (shouldBeSet)
305 setBit (bit);
306 else
307 clearBit (bit);
308}
309
310void BigInteger::clearBit (const int bit) noexcept
311{
312 if (bit >= 0 && bit <= highestBit)
313 {
314 getValues() [bitToIndex (bit)] &= ~bitToMask (bit);
315
316 if (bit == highestBit)
318 }
319}
320
321void BigInteger::setRange (int startBit, int numBits, const bool shouldBeSet)
322{
323 while (--numBits >= 0)
324 setBit (startBit++, shouldBeSet);
325}
326
327void BigInteger::insertBit (const int bit, const bool shouldBeSet)
328{
329 if (bit >= 0)
330 shiftBits (1, bit);
331
332 setBit (bit, shouldBeSet);
333}
334
335//==============================================================================
337{
338 return getHighestBit() < 0;
339}
340
342{
343 return getHighestBit() == 0 && ! negative;
344}
345
347{
348 return negative && ! isZero();
349}
350
351void BigInteger::setNegative (const bool neg) noexcept
352{
353 negative = neg;
354}
355
357{
358 negative = (! negative) && ! isZero();
359}
360
361#if JUCE_MSVC && ! defined (__INTEL_COMPILER)
362 #pragma intrinsic (_BitScanReverse)
363#endif
364
366{
367 int total = 0;
368 auto* values = getValues();
369
370 for (int i = (int) sizeNeededToHold (highestBit); --i >= 0;)
371 total += countNumberOfBits (values[i]);
372
373 return total;
374}
375
377{
378 auto* values = getValues();
379
380 for (int i = (int) bitToIndex (highestBit); i >= 0; --i)
381 if (uint32 n = values[i])
382 return findHighestSetBit (n) + (i << 5);
383
384 return -1;
385}
386
387int BigInteger::findNextSetBit (int i) const noexcept
388{
389 auto* values = getValues();
390
391 for (; i <= highestBit; ++i)
392 if ((values [bitToIndex (i)] & bitToMask (i)) != 0)
393 return i;
394
395 return -1;
396}
397
398int BigInteger::findNextClearBit (int i) const noexcept
399{
400 auto* values = getValues();
401
402 for (; i <= highestBit; ++i)
403 if ((values [bitToIndex (i)] & bitToMask (i)) == 0)
404 break;
405
406 return i;
407}
408
409//==============================================================================
410BigInteger& BigInteger::operator+= (const BigInteger& other)
411{
412 if (this == &other)
413 return operator+= (BigInteger (other));
414
415 if (other.isNegative())
416 return operator-= (-other);
417
418 if (isNegative())
419 {
420 if (compareAbsolute (other) < 0)
421 {
422 auto temp = *this;
423 temp.negate();
424 *this = other;
425 *this -= temp;
426 }
427 else
428 {
429 negate();
430 *this -= other;
431 negate();
432 }
433 }
434 else
435 {
436 highestBit = jmax (highestBit, other.highestBit) + 1;
437
438 auto numInts = sizeNeededToHold (highestBit);
439 auto* values = ensureSize (numInts);
440 auto* otherValues = other.getValues();
441 int64 remainder = 0;
442
443 for (size_t i = 0; i < numInts; ++i)
444 {
445 remainder += values[i];
446
447 if (i < other.allocatedSize)
448 remainder += otherValues[i];
449
450 values[i] = (uint32) remainder;
451 remainder >>= 32;
452 }
453
454 jassert (remainder == 0);
456 }
457
458 return *this;
459}
460
461BigInteger& BigInteger::operator-= (const BigInteger& other)
462{
463 if (this == &other)
464 {
465 clear();
466 return *this;
467 }
468
469 if (other.isNegative())
470 return operator+= (-other);
471
472 if (isNegative())
473 {
474 negate();
475 *this += other;
476 negate();
477 return *this;
478 }
479
480 if (compareAbsolute (other) < 0)
481 {
482 auto temp = other;
483 swapWith (temp);
484 *this -= temp;
485 negate();
486 return *this;
487 }
488
489 auto numInts = sizeNeededToHold (getHighestBit());
490 auto maxOtherInts = sizeNeededToHold (other.getHighestBit());
491 jassert (numInts >= maxOtherInts);
492 auto* values = getValues();
493 auto* otherValues = other.getValues();
494 int64 amountToSubtract = 0;
495
496 for (size_t i = 0; i < numInts; ++i)
497 {
498 if (i < maxOtherInts)
499 amountToSubtract += (int64) otherValues[i];
500
501 if (values[i] >= amountToSubtract)
502 {
503 values[i] = (uint32) (values[i] - amountToSubtract);
504 amountToSubtract = 0;
505 }
506 else
507 {
508 const int64 n = ((int64) values[i] + (((int64) 1) << 32)) - amountToSubtract;
509 values[i] = (uint32) n;
510 amountToSubtract = 1;
511 }
512 }
513
515 return *this;
516}
517
518BigInteger& BigInteger::operator*= (const BigInteger& other)
519{
520 if (this == &other)
521 return operator*= (BigInteger (other));
522
523 auto n = getHighestBit();
524 auto t = other.getHighestBit();
525
526 auto wasNegative = isNegative();
527 setNegative (false);
528
529 BigInteger total;
530 total.highestBit = n + t + 1;
531 auto* totalValues = total.ensureSize (sizeNeededToHold (total.highestBit) + 1);
532
533 n >>= 5;
534 t >>= 5;
535
536 auto m = other;
537 m.setNegative (false);
538
539 auto* mValues = m.getValues();
540 auto* values = getValues();
541
542 for (int i = 0; i <= t; ++i)
543 {
544 uint32 c = 0;
545
546 for (int j = 0; j <= n; ++j)
547 {
548 auto uv = (uint64) totalValues[i + j] + (uint64) values[j] * (uint64) mValues[i] + (uint64) c;
549 totalValues[i + j] = (uint32) uv;
550 c = static_cast<uint32> (uv >> 32);
551 }
552
553 totalValues[i + n + 1] = c;
554 }
555
556 total.highestBit = total.getHighestBit();
557 total.setNegative (wasNegative ^ other.isNegative());
558 swapWith (total);
559
560 return *this;
561}
562
563void BigInteger::divideBy (const BigInteger& divisor, BigInteger& remainder)
564{
565 if (this == &divisor)
566 return divideBy (BigInteger (divisor), remainder);
567
568 jassert (this != &remainder); // (can't handle passing itself in to get the remainder)
569
570 auto divHB = divisor.getHighestBit();
571 auto ourHB = getHighestBit();
572
573 if (divHB < 0 || ourHB < 0)
574 {
575 // division by zero
576 remainder.clear();
577 clear();
578 }
579 else
580 {
581 auto wasNegative = isNegative();
582
583 swapWith (remainder);
584 remainder.setNegative (false);
585 clear();
586
587 BigInteger temp (divisor);
588 temp.setNegative (false);
589
590 auto leftShift = ourHB - divHB;
591 temp <<= leftShift;
592
593 while (leftShift >= 0)
594 {
595 if (remainder.compareAbsolute (temp) >= 0)
596 {
597 remainder -= temp;
598 setBit (leftShift);
599 }
600
601 if (--leftShift >= 0)
602 temp >>= 1;
603 }
604
605 negative = wasNegative ^ divisor.isNegative();
606 remainder.setNegative (wasNegative);
607 }
608}
609
610BigInteger& BigInteger::operator/= (const BigInteger& other)
611{
612 BigInteger remainder;
613 divideBy (other, remainder);
614 return *this;
615}
616
617BigInteger& BigInteger::operator|= (const BigInteger& other)
618{
619 if (this == &other)
620 return *this;
621
622 // this operation doesn't take into account negative values..
623 jassert (isNegative() == other.isNegative());
624
625 if (other.highestBit >= 0)
626 {
627 auto* values = ensureSize (sizeNeededToHold (other.highestBit));
628 auto* otherValues = other.getValues();
629
630 auto n = (int) bitToIndex (other.highestBit) + 1;
631
632 while (--n >= 0)
633 values[n] |= otherValues[n];
634
635 if (other.highestBit > highestBit)
636 highestBit = other.highestBit;
637
639 }
640
641 return *this;
642}
643
644BigInteger& BigInteger::operator&= (const BigInteger& other)
645{
646 if (this == &other)
647 return *this;
648
649 // this operation doesn't take into account negative values..
650 jassert (isNegative() == other.isNegative());
651
652 auto* values = getValues();
653 auto* otherValues = other.getValues();
654
655 auto n = (int) allocatedSize;
656
657 while (n > (int) other.allocatedSize)
658 values[--n] = 0;
659
660 while (--n >= 0)
661 values[n] &= otherValues[n];
662
663 if (other.highestBit < highestBit)
664 highestBit = other.highestBit;
665
667 return *this;
668}
669
670BigInteger& BigInteger::operator^= (const BigInteger& other)
671{
672 if (this == &other)
673 {
674 clear();
675 return *this;
676 }
677
678 // this operation will only work with the absolute values
679 jassert (isNegative() == other.isNegative());
680
681 if (other.highestBit >= 0)
682 {
683 auto* values = ensureSize (sizeNeededToHold (other.highestBit));
684 auto* otherValues = other.getValues();
685
686 auto n = (int) bitToIndex (other.highestBit) + 1;
687
688 while (--n >= 0)
689 values[n] ^= otherValues[n];
690
691 if (other.highestBit > highestBit)
692 highestBit = other.highestBit;
693
695 }
696
697 return *this;
698}
699
700BigInteger& BigInteger::operator%= (const BigInteger& divisor)
701{
702 BigInteger remainder;
703 divideBy (divisor, remainder);
704 swapWith (remainder);
705 return *this;
706}
707
708BigInteger& BigInteger::operator++() { return operator+= (1); }
709BigInteger& BigInteger::operator--() { return operator-= (1); }
710BigInteger BigInteger::operator++ (int) { const auto old (*this); operator+= (1); return old; }
711BigInteger BigInteger::operator-- (int) { const auto old (*this); operator-= (1); return old; }
712
713BigInteger BigInteger::operator-() const { auto b (*this); b.negate(); return b; }
714BigInteger BigInteger::operator+ (const BigInteger& other) const { auto b (*this); return b += other; }
715BigInteger BigInteger::operator- (const BigInteger& other) const { auto b (*this); return b -= other; }
716BigInteger BigInteger::operator* (const BigInteger& other) const { auto b (*this); return b *= other; }
717BigInteger BigInteger::operator/ (const BigInteger& other) const { auto b (*this); return b /= other; }
718BigInteger BigInteger::operator| (const BigInteger& other) const { auto b (*this); return b |= other; }
719BigInteger BigInteger::operator& (const BigInteger& other) const { auto b (*this); return b &= other; }
720BigInteger BigInteger::operator^ (const BigInteger& other) const { auto b (*this); return b ^= other; }
721BigInteger BigInteger::operator% (const BigInteger& other) const { auto b (*this); return b %= other; }
722BigInteger BigInteger::operator<< (const int numBits) const { auto b (*this); return b <<= numBits; }
723BigInteger BigInteger::operator>> (const int numBits) const { auto b (*this); return b >>= numBits; }
724BigInteger& BigInteger::operator<<= (const int numBits) { shiftBits (numBits, 0); return *this; }
725BigInteger& BigInteger::operator>>= (const int numBits) { shiftBits (-numBits, 0); return *this; }
726
727//==============================================================================
728int BigInteger::compare (const BigInteger& other) const noexcept
729{
730 auto isNeg = isNegative();
731
732 if (isNeg == other.isNegative())
733 {
734 auto absComp = compareAbsolute (other);
735 return isNeg ? -absComp : absComp;
736 }
737
738 return isNeg ? -1 : 1;
739}
740
741int BigInteger::compareAbsolute (const BigInteger& other) const noexcept
742{
743 auto h1 = getHighestBit();
744 auto h2 = other.getHighestBit();
745
746 if (h1 > h2) return 1;
747 if (h1 < h2) return -1;
748
749 auto* values = getValues();
750 auto* otherValues = other.getValues();
751
752 for (int i = (int) bitToIndex (h1); i >= 0; --i)
753 if (values[i] != otherValues[i])
754 return values[i] > otherValues[i] ? 1 : -1;
755
756 return 0;
757}
758
759bool BigInteger::operator== (const BigInteger& other) const noexcept { return compare (other) == 0; }
760bool BigInteger::operator!= (const BigInteger& other) const noexcept { return compare (other) != 0; }
761bool BigInteger::operator< (const BigInteger& other) const noexcept { return compare (other) < 0; }
762bool BigInteger::operator<= (const BigInteger& other) const noexcept { return compare (other) <= 0; }
763bool BigInteger::operator> (const BigInteger& other) const noexcept { return compare (other) > 0; }
764bool BigInteger::operator>= (const BigInteger& other) const noexcept { return compare (other) >= 0; }
765
766//==============================================================================
767void BigInteger::shiftLeft (int bits, const int startBit)
768{
769 if (startBit > 0)
770 {
771 for (int i = highestBit; i >= startBit; --i)
772 setBit (i + bits, (*this) [i]);
773
774 while (--bits >= 0)
775 clearBit (bits + startBit);
776 }
777 else
778 {
779 auto* values = ensureSize (sizeNeededToHold (highestBit + bits));
780 auto wordsToMove = bitToIndex (bits);
781 auto numOriginalInts = bitToIndex (highestBit);
782 highestBit += bits;
783
784 if (wordsToMove > 0)
785 {
786 for (int i = (int) numOriginalInts; i >= 0; --i)
787 values[(size_t) i + wordsToMove] = values[i];
788
789 for (size_t j = 0; j < wordsToMove; ++j)
790 values[j] = 0;
791
792 bits &= 31;
793 }
794
795 if (bits != 0)
796 {
797 auto invBits = 32 - bits;
798
799 for (size_t i = bitToIndex (highestBit); i > wordsToMove; --i)
800 values[i] = (values[i] << bits) | (values[i - 1] >> invBits);
801
802 values[wordsToMove] = values[wordsToMove] << bits;
803 }
804
806 }
807}
808
809void BigInteger::shiftRight (int bits, const int startBit)
810{
811 if (startBit > 0)
812 {
813 for (int i = startBit; i <= highestBit; ++i)
814 setBit (i, (*this) [i + bits]);
815
817 }
818 else
819 {
820 if (bits > highestBit)
821 {
822 clear();
823 }
824 else
825 {
826 auto wordsToMove = bitToIndex (bits);
827 auto top = 1 + bitToIndex (highestBit) - wordsToMove;
828 highestBit -= bits;
829 auto* values = getValues();
830
831 if (wordsToMove > 0)
832 {
833 for (size_t i = 0; i < top; ++i)
834 values[i] = values[i + wordsToMove];
835
836 for (size_t i = 0; i < wordsToMove; ++i)
837 values[top + i] = 0;
838
839 bits &= 31;
840 }
841
842 if (bits != 0)
843 {
844 auto invBits = 32 - bits;
845 --top;
846
847 for (size_t i = 0; i < top; ++i)
848 values[i] = (values[i] >> bits) | (values[i + 1] << invBits);
849
850 values[top] = (values[top] >> bits);
851 }
852
854 }
855 }
856}
857
858void BigInteger::shiftBits (int bits, const int startBit)
859{
860 if (highestBit >= 0)
861 {
862 if (bits < 0)
863 shiftRight (-bits, startBit);
864 else if (bits > 0)
865 shiftLeft (bits, startBit);
866 }
867}
868
869//==============================================================================
871{
872 while (! m->isZero())
873 {
874 if (n->compareAbsolute (*m) > 0)
875 std::swap (m, n);
876
877 *m -= *n;
878 }
879
880 return *n;
881}
882
884{
885 auto m = *this;
886
887 while (! n.isZero())
888 {
889 if (std::abs (m.getHighestBit() - n.getHighestBit()) <= 16)
890 return simpleGCD (&m, &n);
891
893 m.divideBy (n, temp2);
894
895 m.swapWith (n);
896 n.swapWith (temp2);
897 }
898
899 return m;
900}
901
902void BigInteger::exponentModulo (const BigInteger& exponent, const BigInteger& modulus)
903{
904 *this %= modulus;
905 auto exp = exponent;
906 exp %= modulus;
907
908 if (modulus.getHighestBit() <= 32 || modulus % 2 == 0)
909 {
910 auto a = *this;
911 auto n = exp.getHighestBit();
912
913 for (int i = n; --i >= 0;)
914 {
915 *this *= *this;
916
917 if (exp[i])
918 *this *= a;
919
920 if (compareAbsolute (modulus) >= 0)
921 *this %= modulus;
922 }
923 }
924 else
925 {
926 auto Rfactor = modulus.getHighestBit() + 1;
927 BigInteger R (1);
928 R.shiftLeft (Rfactor, 0);
929
930 BigInteger R1, m1, g;
931 g.extendedEuclidean (modulus, R, m1, R1);
932
933 if (! g.isOne())
934 {
935 BigInteger a (*this);
936
937 for (int i = exp.getHighestBit(); --i >= 0;)
938 {
939 *this *= *this;
940
941 if (exp[i])
942 *this *= a;
943
944 if (compareAbsolute (modulus) >= 0)
945 *this %= modulus;
946 }
947 }
948 else
949 {
950 auto am = (*this * R) % modulus;
951 auto xm = am;
952 auto um = R % modulus;
953
954 for (int i = exp.getHighestBit(); --i >= 0;)
955 {
956 xm.montgomeryMultiplication (xm, modulus, m1, Rfactor);
957
958 if (exp[i])
959 xm.montgomeryMultiplication (am, modulus, m1, Rfactor);
960 }
961
962 xm.montgomeryMultiplication (1, modulus, m1, Rfactor);
963 swapWith (xm);
964 }
965 }
966}
967
969 const BigInteger& modulusp, const int k)
970{
971 *this *= other;
972 auto t = *this;
973
974 setRange (k, highestBit - k + 1, false);
975 *this *= modulusp;
976
977 setRange (k, highestBit - k + 1, false);
978 *this *= modulus;
979 *this += t;
980 shiftRight (k, 0);
981
982 if (compare (modulus) >= 0)
983 *this -= modulus;
984 else if (isNegative())
985 *this += modulus;
986}
987
990{
991 BigInteger p(a), q(b), gcd(1);
992 Array<BigInteger> tempValues;
993
994 while (! q.isZero())
995 {
996 tempValues.add (p / q);
997 gcd = q;
998 q = p % q;
999 p = gcd;
1000 }
1001
1002 x.clear();
1003 y = 1;
1004
1005 for (int i = 1; i < tempValues.size(); ++i)
1006 {
1007 auto& v = tempValues.getReference (tempValues.size() - i - 1);
1008
1009 if ((i & 1) != 0)
1010 x += y * v;
1011 else
1012 y += x * v;
1013 }
1014
1015 if (gcd.compareAbsolute (y * b - x * a) != 0)
1016 {
1017 x.negate();
1018 x.swapWith (y);
1019 x.negate();
1020 }
1021
1022 swapWith (gcd);
1023}
1024
1026{
1027 if (modulus.isOne() || modulus.isNegative())
1028 {
1029 clear();
1030 return;
1031 }
1032
1033 if (isNegative() || compareAbsolute (modulus) >= 0)
1034 *this %= modulus;
1035
1036 if (isOne())
1037 return;
1038
1039 if (findGreatestCommonDivisor (modulus) != 1)
1040 {
1041 clear(); // not invertible!
1042 return;
1043 }
1044
1045 BigInteger a1 (modulus), a2 (*this),
1046 b1 (modulus), b2 (1);
1047
1048 while (! a2.isOne())
1049 {
1050 BigInteger temp1, multiplier (a1);
1051 multiplier.divideBy (a2, temp1);
1052
1053 temp1 = a2;
1054 temp1 *= multiplier;
1055 auto temp2 = a1;
1056 temp2 -= temp1;
1057 a1 = a2;
1058 a2 = temp2;
1059
1060 temp1 = b2;
1061 temp1 *= multiplier;
1062 temp2 = b1;
1063 temp2 -= temp1;
1064 b1 = b2;
1065 b2 = temp2;
1066 }
1067
1068 while (b2.isNegative())
1069 b2 += modulus;
1070
1071 b2 %= modulus;
1072 swapWith (b2);
1073}
1074
1075//==============================================================================
1077{
1078 return stream << value.toString (10);
1079}
1080
1081String BigInteger::toString (const int base, const int minimumNumCharacters) const
1082{
1083 String s;
1084 auto v = *this;
1085
1086 if (base == 2 || base == 8 || base == 16)
1087 {
1088 auto bits = (base == 2) ? 1 : (base == 8 ? 3 : 4);
1089 static const char hexDigits[] = "0123456789abcdef";
1090
1091 for (;;)
1092 {
1093 auto remainder = v.getBitRangeAsInt (0, bits);
1094 v >>= bits;
1095
1096 if (remainder == 0 && v.isZero())
1097 break;
1098
1099 s = String::charToString ((juce_wchar) (uint8) hexDigits [remainder]) + s;
1100 }
1101 }
1102 else if (base == 10)
1103 {
1104 const BigInteger ten (10);
1105 BigInteger remainder;
1106
1107 for (;;)
1108 {
1109 v.divideBy (ten, remainder);
1110
1111 if (remainder.isZero() && v.isZero())
1112 break;
1113
1114 s = String (remainder.getBitRangeAsInt (0, 8)) + s;
1115 }
1116 }
1117 else
1118 {
1119 jassertfalse; // can't do the specified base!
1120 return {};
1121 }
1122
1123 s = s.paddedLeft ('0', minimumNumCharacters);
1124
1125 return isNegative() ? "-" + s : s;
1126}
1127
1129{
1130 clear();
1131 auto t = text.text.findEndOfWhitespace();
1132
1133 setNegative (*t == (juce_wchar) '-');
1134
1135 if (base == 2 || base == 8 || base == 16)
1136 {
1137 auto bits = (base == 2) ? 1 : (base == 8 ? 3 : 4);
1138
1139 for (;;)
1140 {
1141 auto c = t.getAndAdvance();
1143
1144 if (((uint32) digit) < (uint32) base)
1145 {
1146 *this <<= bits;
1147 *this += digit;
1148 }
1149 else if (c == 0)
1150 {
1151 break;
1152 }
1153 }
1154 }
1155 else if (base == 10)
1156 {
1157 const BigInteger ten ((uint32) 10);
1158
1159 for (;;)
1160 {
1161 auto c = t.getAndAdvance();
1162
1163 if (c >= '0' && c <= '9')
1164 {
1165 *this *= ten;
1166 *this += (int) (c - '0');
1167 }
1168 else if (c == 0)
1169 {
1170 break;
1171 }
1172 }
1173 }
1174}
1175
1177{
1178 auto numBytes = (getHighestBit() + 8) >> 3;
1179 MemoryBlock mb ((size_t) numBytes);
1180 auto* values = getValues();
1181
1182 for (int i = 0; i < numBytes; ++i)
1183 mb[i] = (char) ((values[i / 4] >> ((i & 3) * 8)) & 0xff);
1184
1185 return mb;
1186}
1187
1189{
1190 auto numBytes = data.getSize();
1191 auto numInts = 1 + (numBytes / sizeof (uint32));
1192 auto* values = ensureSize (numInts);
1193
1194 for (int i = 0; i < (int) numInts - 1; ++i)
1195 values[i] = (uint32) ByteOrder::littleEndianInt (addBytesToPointer (data.getData(), (size_t) i * sizeof (uint32)));
1196
1197 values[numInts - 1] = 0;
1198
1199 for (int i = (int) (numBytes & ~3u); i < (int) numBytes; ++i)
1200 this->setBitRangeAsInt (i << 3, 8, (uint32) data [i]);
1201
1202 highestBit = (int) numBytes * 8;
1204}
1205
1206//==============================================================================
1207void writeLittleEndianBitsInBuffer (void* buffer, uint32 startBit, uint32 numBits, uint32 value) noexcept
1208{
1209 jassert (buffer != nullptr);
1210 jassert (numBits > 0 && numBits <= 32);
1211 jassert (numBits == 32 || (value >> numBits) == 0);
1212
1213 uint8* data = static_cast<uint8*> (buffer) + startBit / 8;
1214
1215 if (const uint32 offset = (startBit & 7))
1216 {
1217 const uint32 bitsInByte = 8 - offset;
1218 const uint8 current = *data;
1219
1220 if (bitsInByte >= numBits)
1221 {
1222 *data = (uint8) ((current & ~(((1u << numBits) - 1u) << offset)) | (value << offset));
1223 return;
1224 }
1225
1226 *data++ = current ^ (uint8) (((value << offset) ^ current) & (((1u << bitsInByte) - 1u) << offset));
1227 numBits -= bitsInByte;
1228 value >>= bitsInByte;
1229 }
1230
1231 while (numBits >= 8)
1232 {
1233 *data++ = (uint8) value;
1234 value >>= 8;
1235 numBits -= 8;
1236 }
1237
1238 if (numBits > 0)
1239 *data = (uint8) ((*data & (uint32) (0xff << numBits)) | value);
1240}
1241
1242uint32 readLittleEndianBitsInBuffer (const void* buffer, uint32 startBit, uint32 numBits) noexcept
1243{
1244 jassert (buffer != nullptr);
1245 jassert (numBits > 0 && numBits <= 32);
1246
1247 uint32 result = 0;
1248 uint32 bitsRead = 0;
1249 const uint8* data = static_cast<const uint8*> (buffer) + startBit / 8;
1250
1251 if (const uint32 offset = (startBit & 7))
1252 {
1253 const uint32 bitsInByte = 8 - offset;
1254 result = (uint32) (*data >> offset);
1255
1256 if (bitsInByte >= numBits)
1257 return result & ((1u << numBits) - 1u);
1258
1259 numBits -= bitsInByte;
1260 bitsRead += bitsInByte;
1261 ++data;
1262 }
1263
1264 while (numBits >= 8)
1265 {
1266 result |= (((uint32) *data++) << bitsRead);
1267 bitsRead += 8;
1268 numBits -= 8;
1269 }
1270
1271 if (numBits > 0)
1272 result |= ((*data & ((1u << numBits) - 1u)) << bitsRead);
1273
1274 return result;
1275}
1276
1277
1278//==============================================================================
1279//==============================================================================
1280#if JUCE_UNIT_TESTS
1281
1282class BigIntegerTests : public UnitTest
1283{
1284public:
1285 BigIntegerTests()
1286 : UnitTest ("BigInteger", UnitTestCategories::maths)
1287 {}
1288
1289 static BigInteger getBigRandom (Random& r)
1290 {
1291 BigInteger b;
1292
1293 while (b < 2)
1294 r.fillBitsRandomly (b, 0, r.nextInt (150) + 1);
1295
1296 return b;
1297 }
1298
1299 void runTest() override
1300 {
1301 {
1302 beginTest ("BigInteger");
1303
1304 Random r = getRandom();
1305
1306 expect (BigInteger().isZero());
1307 expect (BigInteger(1).isOne());
1308
1309 for (int j = 10000; --j >= 0;)
1310 {
1311 BigInteger b1 (getBigRandom(r)),
1312 b2 (getBigRandom(r));
1313
1314 BigInteger b3 = b1 + b2;
1315 expect (b3 > b1 && b3 > b2);
1316 expect (b3 - b1 == b2);
1317 expect (b3 - b2 == b1);
1318
1319 BigInteger b4 = b1 * b2;
1320 expect (b4 > b1 && b4 > b2);
1321 expect (b4 / b1 == b2);
1322 expect (b4 / b2 == b1);
1323 expect (((b4 << 1) >> 1) == b4);
1324 expect (((b4 << 10) >> 10) == b4);
1325 expect (((b4 << 100) >> 100) == b4);
1326
1327 // TODO: should add tests for other ops (although they also get pretty well tested in the RSA unit test)
1328
1329 BigInteger b5;
1330 b5.loadFromMemoryBlock (b3.toMemoryBlock());
1331 expect (b3 == b5);
1332 }
1333 }
1334
1335 {
1336 beginTest ("Bit setting");
1337
1338 Random r = getRandom();
1339 static uint8 test[2048];
1340
1341 for (int j = 100000; --j >= 0;)
1342 {
1343 uint32 offset = static_cast<uint32> (r.nextInt (200) + 10);
1344 uint32 num = static_cast<uint32> (r.nextInt (32) + 1);
1345 uint32 value = static_cast<uint32> (r.nextInt());
1346
1347 if (num < 32)
1348 value &= ((1u << num) - 1);
1349
1350 auto old1 = readLittleEndianBitsInBuffer (test, offset - 6, 6);
1351 auto old2 = readLittleEndianBitsInBuffer (test, offset + num, 6);
1353 auto result = readLittleEndianBitsInBuffer (test, offset, num);
1354
1355 expect (result == value);
1356 expect (old1 == readLittleEndianBitsInBuffer (test, offset - 6, 6));
1357 expect (old2 == readLittleEndianBitsInBuffer (test, offset + num, 6));
1358 }
1359 }
1360 }
1361};
1362
1363static BigIntegerTests bigIntegerTests;
1364
1365#endif
1366
1367} // namespace juce
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
static const unsigned char temp2[]
Definition DistrhoArtwork3BandEQ.cpp:2750
static const unsigned char temp1[]
Definition DistrhoArtwork3BandEQ.cpp:5
#define noexcept
Definition DistrhoDefines.h:72
uint8_t a
Definition Spc_Cpu.h:141
ostream & operator<<(ostream &out, const MidiEvent &ev)
Definition InMgr.cpp:9
uint8_t uint8
Definition basics.h:86
uint32_t uint32
Definition basics.h:90
static uint32 littleEndianInt(const void *bytes) noexcept
Definition ByteOrder.h:236
static String charToString(water_uchar character)
Definition String.cpp:311
Definition juce_Array.h:56
int size() const noexcept
Definition juce_Array.h:215
void add(const ElementType &newElement)
Definition juce_Array.h:418
ElementType & getReference(int index) noexcept
Definition juce_Array.h:267
Definition juce_BigInteger.h:39
MemoryBlock toMemoryBlock() const
Definition juce_BigInteger.cpp:1176
@ numPreallocatedInts
Definition juce_BigInteger.h:324
void shiftLeft(int bits, int startBit)
Definition juce_BigInteger.cpp:767
bool isOne() const noexcept
Definition juce_BigInteger.cpp:341
void clearBit(int bitNumber) noexcept
Definition juce_BigInteger.cpp:310
BigInteger getBitRange(int startBit, int numBits) const
Definition juce_BigInteger.cpp:217
void parseString(StringRef text, int base)
Definition juce_BigInteger.cpp:1128
uint32 preallocated[numPreallocatedInts]
Definition juce_BigInteger.h:326
int64 toInt64() const noexcept
Definition juce_BigInteger.cpp:210
BigInteger & operator++()
Definition juce_BigInteger.cpp:708
void exponentModulo(const BigInteger &exponent, const BigInteger &modulus)
Definition juce_BigInteger.cpp:902
void setNegative(bool shouldBeNegative) noexcept
Definition juce_BigInteger.cpp:351
uint32 getBitRangeAsInt(int startBit, int numBits) const noexcept
Definition juce_BigInteger.cpp:235
bool negative
Definition juce_BigInteger.h:329
void clear() noexcept
Definition juce_BigInteger.cpp:277
BigInteger findGreatestCommonDivisor(BigInteger other) const
Definition juce_BigInteger.cpp:883
uint32 * getValues() const noexcept
Definition juce_BigInteger.cpp:165
HeapBlock< uint32 > heapAllocation
Definition juce_BigInteger.h:325
void shiftRight(int bits, int startBit)
Definition juce_BigInteger.cpp:809
void extendedEuclidean(const BigInteger &a, const BigInteger &b, BigInteger &xOut, BigInteger &yOut)
Definition juce_BigInteger.cpp:988
void setRange(int startBit, int numBits, bool shouldBeSet)
Definition juce_BigInteger.cpp:321
void shiftBits(int howManyBitsLeft, int startBit)
Definition juce_BigInteger.cpp:858
int getHighestBit() const noexcept
Definition juce_BigInteger.cpp:376
BigInteger & operator--()
Definition juce_BigInteger.cpp:709
void divideBy(const BigInteger &divisor, BigInteger &remainder)
Definition juce_BigInteger.cpp:563
String toString(int base, int minimumNumCharacters=1) const
Definition juce_BigInteger.cpp:1081
int findNextClearBit(int startIndex) const noexcept
Definition juce_BigInteger.cpp:398
int compare(const BigInteger &other) const noexcept
Definition juce_BigInteger.cpp:728
BigInteger()
Definition juce_BigInteger.cpp:54
BigInteger operator-() const
Definition juce_BigInteger.cpp:713
size_t allocatedSize
Definition juce_BigInteger.h:327
void negate() noexcept
Definition juce_BigInteger.cpp:356
void setBit(int bitNumber)
Definition juce_BigInteger.cpp:288
void setBitRangeAsInt(int startBit, int numBits, uint32 valueToSet)
Definition juce_BigInteger.cpp:261
int findNextSetBit(int startIndex) const noexcept
Definition juce_BigInteger.cpp:387
uint32 * ensureSize(size_t)
Definition juce_BigInteger.cpp:173
void loadFromMemoryBlock(const MemoryBlock &data)
Definition juce_BigInteger.cpp:1188
bool isZero() const noexcept
Definition juce_BigInteger.cpp:336
int countNumberOfSetBits() const noexcept
Definition juce_BigInteger.cpp:365
void swapWith(BigInteger &) noexcept
Definition juce_BigInteger.cpp:133
void montgomeryMultiplication(const BigInteger &other, const BigInteger &modulus, const BigInteger &modulusp, int k)
Definition juce_BigInteger.cpp:968
bool isNegative() const noexcept
Definition juce_BigInteger.cpp:346
int highestBit
Definition juce_BigInteger.h:328
int compareAbsolute(const BigInteger &other) const noexcept
Definition juce_BigInteger.cpp:741
void insertBit(int bitNumber, bool shouldBeSet)
Definition juce_BigInteger.cpp:327
int toInteger() const noexcept
Definition juce_BigInteger.cpp:204
void inverseModulo(const BigInteger &modulus)
Definition juce_BigInteger.cpp:1025
static int getHexDigitValue(juce_wchar digit) noexcept
Definition juce_CharacterFunctions.cpp:112
Definition juce_MemoryBlock.h:33
Definition juce_OutputStream.h:38
Definition juce_String.h:53
Definition juce_StringRef.h:62
unsigned * m
Definition inflate.c:1559
struct huft * t
Definition inflate.c:943
register unsigned k
Definition inflate.c:946
register unsigned j
Definition inflate.c:1576
int y
Definition inflate.c:1588
unsigned v[N_MAX]
Definition inflate.c:1584
int g
Definition inflate.c:1573
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
unsigned x[BMAX+1]
Definition inflate.c:1586
static PuglViewHint int value
Definition pugl.h:1708
JSAMPIMAGE data
Definition jpeglib.h:945
#define jassert(expression)
#define jassertfalse
#define JUCE_CALLTYPE
Definition carla_juce.cpp:31
unsigned long long uint64
Definition juce_MathsFunctions.h:56
constexpr Type jmin(Type a, Type b)
Definition juce_MathsFunctions.h:106
int findHighestSetBit(uint32 n) noexcept
Definition juce_BigInteger.cpp:33
unsigned int uint32
Definition juce_MathsFunctions.h:45
constexpr Type jmax(Type a, Type b)
Definition juce_MathsFunctions.h:94
uint32 readLittleEndianBitsInBuffer(const void *buffer, uint32 startBit, uint32 numBits) noexcept
Definition juce_BigInteger.cpp:1242
long long int64
Definition juce_MathsFunctions.h:54
void writeLittleEndianBitsInBuffer(void *buffer, uint32 startBit, uint32 numBits, uint32 value) noexcept
Definition juce_BigInteger.cpp:1207
wchar_t juce_wchar
Definition juce_CharacterFunctions.h:42
int countNumberOfBits(uint32 n) noexcept
Definition juce_MathsFunctions.h:551
static const char hexDigits[]
Definition juce_String.cpp:1899
Type * addBytesToPointer(Type *basePointer, IntegerType bytes) noexcept
Definition juce_Memory.h:111
signed int int32
Definition juce_MathsFunctions.h:43
unsigned char uint8
Definition juce_MathsFunctions.h:37
static BigInteger simpleGCD(BigInteger *m, BigInteger *n)
Definition juce_BigInteger.cpp:870
static int test(SerdEnv *env, bool top_level, bool pretty_numbers)
Definition sratom_test.c:79
const char * text
Definition swell-functions.h:167
int n
Definition crypt.c:458
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
memcpy(hh, h, RAND_HEAD_LEN)
int r
Definition crypt.c:458
b
Definition crypt.c:628
register uch * q
Definition fileio.c:817
int result
Definition process.c:1455
typedef int(UZ_EXP MsgFn)()
int negative
Definition zipinfo.c:455
#define const
Definition zconf.h:137