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; }
33int findHighestSetBit (uint32 n)
noexcept
37 #if JUCE_GCC || JUCE_CLANG
38 return 31 - __builtin_clz (n);
40 unsigned long highest;
41 _BitScanReverse (&highest, n);
49 return countNumberOfBits (n >> 1);
55 : allocatedSize (numPreallocatedInts)
57 for (
int i = 0; i < numPreallocatedInts; ++i)
62 : allocatedSize (numPreallocatedInts),
66 preallocated[0] = (uint32) std::abs (value);
68 for (
int i = 1; i < numPreallocatedInts; ++i)
75 : allocatedSize (numPreallocatedInts),
78 preallocated[0] = value;
80 for (
int i = 1; i < numPreallocatedInts; ++i)
87 : allocatedSize (numPreallocatedInts),
94 preallocated[0] = (uint32) value;
95 preallocated[1] = (uint32) (value >> 32);
97 for (
int i = 2; i < numPreallocatedInts; ++i)
104 : allocatedSize (other.allocatedSize),
106 negative (other.negative)
108 if (allocatedSize > numPreallocatedInts)
109 heapAllocation.malloc (allocatedSize);
111 memcpy (getValues(), other.getValues(), sizeof (uint32) * allocatedSize);
115 : heapAllocation (std::move (other.heapAllocation)),
116 allocatedSize (other.allocatedSize),
117 highestBit (other.highestBit),
118 negative (other.negative)
120 memcpy (preallocated, other.preallocated, sizeof (preallocated));
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;
135 for (
int i = 0; i < numPreallocatedInts; ++i)
136 std::swap (preallocated[i], other.preallocated[i]);
138 heapAllocation.swapWith (other.heapAllocation);
139 std::swap (allocatedSize, other.allocatedSize);
140 std::swap (highestBit, other.highestBit);
141 std::swap (negative, other.negative);
148 highestBit = other.getHighestBit();
149 auto newAllocatedSize = (size_t) jmax ((
size_t) numPreallocatedInts, sizeNeededToHold (highestBit));
151 if (newAllocatedSize <= numPreallocatedInts)
152 heapAllocation.free();
153 else if (newAllocatedSize != allocatedSize)
154 heapAllocation.malloc (newAllocatedSize);
156 allocatedSize = newAllocatedSize;
158 memcpy (getValues(), other.getValues(), sizeof (uint32) * allocatedSize);
159 negative = other.negative;
167uint32* BigInteger::getValues() const noexcept
169 jassert (heapAllocation !=
nullptr || allocatedSize <= numPreallocatedInts);
171 return heapAllocation !=
nullptr ? heapAllocation
172 :
const_cast<uint32*
> (preallocated);
175uint32* BigInteger::ensureSize (
const size_t numVals)
177 if (numVals > allocatedSize)
179 auto oldSize = allocatedSize;
180 allocatedSize = ((numVals + 2) * 3) / 2;
182 if (heapAllocation ==
nullptr)
184 heapAllocation.
calloc (allocatedSize);
185 memcpy (heapAllocation, preallocated,
sizeof (uint32) * numPreallocatedInts);
189 heapAllocation.realloc (allocatedSize);
191 for (
auto* values = getValues(); oldSize < allocatedSize; ++oldSize)
202 return bit <= highestBit && bit >= 0
203 && ((getValues() [bitToIndex (bit)] & bitToMask (bit)) != 0);
208 auto n = (int) (getValues()[0] & 0x7fffffff);
209 return negative ? -n : n;
214 auto* values = getValues();
215 auto n = (((int64) (values[1] & 0x7fffffff)) << 32) | values[0];
216 return negative ? -n : n;
222 numBits = jmax (0, jmin (numBits,
getHighestBit() + 1 - startBit));
223 auto* destValues = r.ensureSize (sizeNeededToHold (numBits));
224 r.highestBit = numBits;
226 for (
int i = 0; numBits > 0;)
245 numBits = jmin (numBits, highestBit + 1 - startBit);
250 auto pos = bitToIndex (startBit);
251 auto offset = startBit & 31;
252 auto endSpace = 32 - numBits;
253 auto* values = getValues();
255 auto n = ((uint32) values [pos]) >> offset;
257 if (offset > endSpace)
258 n |= ((uint32) values [pos + 1]) << (32 - offset);
260 return n & (((uint32) 0xffffffff) >> endSpace);
271 for (
int i = 0; i < numBits; ++i)
273 setBit (startBit + i, (valueToSet & 1) != 0);
283 heapAllocation.free();
284 allocatedSize = numPreallocatedInts;
288 for (
int i = 0; i < numPreallocatedInts; ++i)
298 if (bit > highestBit)
300 ensureSize (sizeNeededToHold (bit));
304 getValues() [bitToIndex (bit)] |= bitToMask (bit);
322 if (bit >= 0 && bit <= highestBit)
324 getValues() [bitToIndex (bit)] &= ~bitToMask (bit);
326 if (bit == highestBit)
335 while (--numBits >= 0)
336 setBit (startBit++, shouldBeSet);
346 setBit (bit, shouldBeSet);
363 return negative && !
isZero();
373 negative = (! negative) && !
isZero();
376#if JUCE_MSVC && ! defined (__INTEL_COMPILER)
377 #pragma intrinsic (_BitScanReverse)
383 auto* values = getValues();
385 for (
int i = (
int) sizeNeededToHold (highestBit); --i >= 0;)
386 total += countNumberOfBits (values[i]);
393 auto* values = getValues();
395 for (
int i = (
int) bitToIndex (highestBit); i >= 0; --i)
396 if (uint32 n = values[i])
397 return findHighestSetBit (n) + (i << 5);
404 auto* values = getValues();
406 for (; i <= highestBit; ++i)
407 if ((values [bitToIndex (i)] & bitToMask (i)) != 0)
415 auto* values = getValues();
417 for (; i <= highestBit; ++i)
418 if ((values [bitToIndex (i)] & bitToMask (i)) == 0)
430 if (other.isNegative())
431 return operator-= (-other);
451 highestBit = jmax (highestBit, other.highestBit) + 1;
453 auto numInts = sizeNeededToHold (highestBit);
454 auto* values = ensureSize (numInts);
455 auto* otherValues = other.getValues();
458 for (
size_t i = 0; i < numInts; ++i)
460 remainder += values[i];
462 if (i < other.allocatedSize)
463 remainder += otherValues[i];
465 values[i] = (uint32) remainder;
469 jassert (remainder == 0);
484 if (other.isNegative())
485 return operator+= (-other);
505 auto maxOtherInts = sizeNeededToHold (other.getHighestBit());
506 jassert (numInts >= maxOtherInts);
507 auto* values = getValues();
508 auto* otherValues = other.getValues();
509 int64 amountToSubtract = 0;
511 for (
size_t i = 0; i < numInts; ++i)
513 if (i < maxOtherInts)
514 amountToSubtract += (int64) otherValues[i];
516 if (values[i] >= amountToSubtract)
518 values[i] = (uint32) (values[i] - amountToSubtract);
519 amountToSubtract = 0;
523 const int64 n = ((int64) values[i] + (((int64) 1) << 32)) - amountToSubtract;
524 values[i] = (uint32) n;
525 amountToSubtract = 1;
539 auto t = other.getHighestBit();
545 total.highestBit = n + t + 1;
546 auto* totalValues = total.ensureSize (sizeNeededToHold (total.highestBit) + 1);
552 m.setNegative (
false);
554 auto* mValues = m.getValues();
555 auto* values = getValues();
557 for (
int i = 0; i <= t; ++i)
561 for (
int j = 0; j <= n; ++j)
563 auto uv = (uint64) totalValues[i + j] + (uint64) values[j] * (uint64) mValues[i] + (uint64) c;
564 totalValues[i + j] = (uint32) uv;
565 c =
static_cast<uint32
> (uv >> 32);
568 totalValues[i + n + 1] = c;
571 total.highestBit = total.getHighestBit();
572 total.setNegative (wasNegative ^ other.isNegative());
580 if (
this == &divisor)
583 jassert (
this != &remainder);
588 if (divHB < 0 || ourHB < 0)
605 auto leftShift = ourHB - divHB;
608 while (leftShift >= 0)
616 if (--leftShift >= 0)
620 negative = wasNegative ^ divisor.
isNegative();
632BigInteger& BigInteger::operator|= (
const BigInteger& other)
640 if (other.highestBit >= 0)
642 auto* values = ensureSize (sizeNeededToHold (other.highestBit));
643 auto* otherValues = other.getValues();
645 auto n = (int) bitToIndex (other.highestBit) + 1;
648 values[n] |= otherValues[n];
650 if (other.highestBit > highestBit)
651 highestBit = other.highestBit;
667 auto* values = getValues();
668 auto* otherValues = other.getValues();
670 auto n = (int) allocatedSize;
672 while (n > (
int) other.allocatedSize)
676 values[n] &= otherValues[n];
678 if (other.highestBit < highestBit)
679 highestBit = other.highestBit;
696 if (other.highestBit >= 0)
698 auto* values = ensureSize (sizeNeededToHold (other.highestBit));
699 auto* otherValues = other.getValues();
701 auto n = (int) bitToIndex (other.highestBit) + 1;
704 values[n] ^= otherValues[n];
706 if (other.highestBit > highestBit)
707 highestBit = other.highestBit;
723BigInteger& BigInteger::operator++() {
return operator+= (1); }
724BigInteger& BigInteger::operator--() {
return operator-= (1); }
725BigInteger BigInteger::operator++ (
int) {
const auto old (*
this); operator+= (1);
return old; }
726BigInteger BigInteger::operator-- (
int) {
const auto old (*
this); operator-= (1);
return old; }
728BigInteger BigInteger::operator-()
const {
auto b (*
this); b.negate();
return b; }
729BigInteger BigInteger::operator+ (
const BigInteger& other)
const {
auto b (*
this);
return b += other; }
730BigInteger BigInteger::operator- (
const BigInteger& other)
const {
auto b (*
this);
return b -= other; }
731BigInteger BigInteger::operator* (
const BigInteger& other)
const {
auto b (*
this);
return b *= other; }
732BigInteger BigInteger::operator/ (
const BigInteger& other)
const {
auto b (*
this);
return b /= other; }
733BigInteger BigInteger::operator| (
const BigInteger& other)
const {
auto b (*
this);
return b |= other; }
734BigInteger BigInteger::operator& (
const BigInteger& other)
const {
auto b (*
this);
return b &= other; }
735BigInteger BigInteger::operator^ (
const BigInteger& other)
const {
auto b (*
this);
return b ^= other; }
736BigInteger BigInteger::operator% (
const BigInteger& other)
const {
auto b (*
this);
return b %= other; }
737BigInteger BigInteger::operator<< (
const int numBits)
const {
auto b (*
this);
return b <<= numBits; }
738BigInteger BigInteger::operator>> (
const int numBits)
const {
auto b (*
this);
return b >>= numBits; }
739BigInteger& BigInteger::operator<<= (
const int numBits) {
shiftBits (numBits, 0);
return *
this; }
740BigInteger& BigInteger::operator>>= (
const int numBits) {
shiftBits (-numBits, 0);
return *
this; }
747 if (isNeg == other.isNegative())
750 return isNeg ? -absComp : absComp;
753 return isNeg ? -1 : 1;
759 auto h2 = other.getHighestBit();
761 if (h1 > h2)
return 1;
762 if (h1 < h2)
return -1;
764 auto* values = getValues();
765 auto* otherValues = other.getValues();
767 for (
int i = (
int) bitToIndex (h1); i >= 0; --i)
768 if (values[i] != otherValues[i])
769 return values[i] > otherValues[i] ? 1 : -1;
774bool BigInteger::operator== (
const BigInteger& other)
const noexcept {
return compare (other) == 0; }
775bool BigInteger::operator!= (
const BigInteger& other)
const noexcept {
return compare (other) != 0; }
776bool BigInteger::operator< (
const BigInteger& other)
const noexcept {
return compare (other) < 0; }
777bool BigInteger::operator<= (
const BigInteger& other)
const noexcept {
return compare (other) <= 0; }
778bool BigInteger::operator> (
const BigInteger& other)
const noexcept {
return compare (other) > 0; }
779bool BigInteger::operator>= (
const BigInteger& other)
const noexcept {
return compare (other) >= 0; }
782void BigInteger::shiftLeft (
int bits,
const int startBit)
786 for (
int i = highestBit; i >= startBit; --i)
787 setBit (i + bits, (*
this) [i]);
794 auto* values = ensureSize (sizeNeededToHold (highestBit + bits));
795 auto wordsToMove = bitToIndex (bits);
796 auto numOriginalInts = bitToIndex (highestBit);
801 for (
int i = (
int) numOriginalInts; i >= 0; --i)
802 values[(
size_t) i + wordsToMove] = values[i];
804 for (
size_t j = 0; j < wordsToMove; ++j)
812 auto invBits = 32 - bits;
814 for (
size_t i = bitToIndex (highestBit); i > wordsToMove; --i)
815 values[i] = (values[i] << bits) | (values[i - 1] >> invBits);
817 values[wordsToMove] = values[wordsToMove] << bits;
824void BigInteger::shiftRight (
int bits,
const int startBit)
828 for (
int i = startBit; i <= highestBit; ++i)
829 setBit (i, (*
this) [i + bits]);
835 if (bits > highestBit)
841 auto wordsToMove = bitToIndex (bits);
842 auto top = 1 + bitToIndex (highestBit) - wordsToMove;
844 auto* values = getValues();
848 for (
size_t i = 0; i < top; ++i)
849 values[i] = values[i + wordsToMove];
851 for (
size_t i = 0; i < wordsToMove; ++i)
859 auto invBits = 32 - bits;
862 for (
size_t i = 0; i < top; ++i)
863 values[i] = (values[i] >> bits) | (values[i + 1] << invBits);
865 values[top] = (values[top] >> bits);
878 shiftRight (-bits, startBit);
880 shiftLeft (bits, startBit);
907 return simpleGCD (&m, &n);
930 for (
int i = n; --i >= 0;)
945 R.shiftLeft (Rfactor, 0);
954 for (
int i = exp.getHighestBit(); --i >= 0;)
967 auto am = (*
this * R) % modulus;
969 auto um = R % modulus;
971 for (
int i = exp.getHighestBit(); --i >= 0;)
973 xm.montgomeryMultiplication (xm, modulus, m1, Rfactor);
976 xm.montgomeryMultiplication (am, modulus, m1, Rfactor);
991 setRange (k, highestBit - k + 1,
false);
994 setRange (k, highestBit - k + 1,
false);
1011 while (! q.isZero())
1013 tempValues.
add (p / q);
1022 for (
int i = 1; i < tempValues.
size(); ++i)
1063 b1 (modulus), b2 (1);
1065 while (! a2.isOne())
1071 temp1 *= multiplier;
1078 temp1 *= multiplier;
1095 return stream << value.
toString (10);
1103 if (base == 2 || base == 8 || base == 16)
1105 auto bits = (base == 2) ? 1 : (base == 8 ? 3 : 4);
1106 static const char hexDigits[] =
"0123456789abcdef";
1110 auto remainder = v.getBitRangeAsInt (0, bits);
1113 if (remainder == 0 && v.isZero())
1119 else if (base == 10)
1126 v.divideBy (ten, remainder);
1128 if (remainder.
isZero() && v.isZero())
1140 s = s.
paddedLeft (
'0', minimumNumCharacters);
1148 auto t = text.
text.findEndOfWhitespace();
1152 if (base == 2 || base == 8 || base == 16)
1154 auto bits = (base == 2) ? 1 : (base == 8 ? 3 : 4);
1158 auto c = t.getAndAdvance();
1161 if (((uint32) digit) < (uint32) base)
1172 else if (base == 10)
1178 auto c = t.getAndAdvance();
1180 if (c >=
'0' && c <=
'9')
1183 *
this += (int) (c -
'0');
1197 auto* values = getValues();
1199 for (
int i = 0; i < numBytes; ++i)
1200 mb[i] = (
char) ((values[i / 4] >> ((i & 3) * 8)) & 0xff);
1207 auto numBytes = data.
getSize();
1208 auto numInts = 1 + (numBytes /
sizeof (uint32));
1209 auto* values = ensureSize (numInts);
1211 for (
int i = 0; i < (int) numInts - 1; ++i)
1214 values[numInts - 1] = 0;
1216 for (
int i = (
int) (numBytes & ~3u); i < (int) numBytes; ++i)
1219 highestBit = (int) numBytes * 8;
1224void writeLittleEndianBitsInBuffer (
void* buffer, uint32 startBit, uint32 numBits, uint32 value)
noexcept
1226 jassert (buffer !=
nullptr);
1227 jassert (numBits > 0 && numBits <= 32);
1228 jassert (numBits == 32 || (value >> numBits) == 0);
1230 uint8* data =
static_cast<uint8*
> (buffer) + startBit / 8;
1232 if (
const uint32 offset = (startBit & 7))
1234 const uint32 bitsInByte = 8 - offset;
1235 const uint8 current = *data;
1237 if (bitsInByte >= numBits)
1239 *data = (uint8) ((current & ~(((1u << numBits) - 1u) << offset)) | (value << offset));
1243 *data++ = current ^ (uint8) (((value << offset) ^ current) & (((1u << bitsInByte) - 1u) << offset));
1244 numBits -= bitsInByte;
1245 value >>= bitsInByte;
1248 while (numBits >= 8)
1250 *data++ = (uint8) value;
1256 *data = (uint8) ((*data & (uint32) (0xff << numBits)) | value);
1259uint32 readLittleEndianBitsInBuffer (
const void* buffer, uint32 startBit, uint32 numBits)
noexcept
1261 jassert (buffer !=
nullptr);
1262 jassert (numBits > 0 && numBits <= 32);
1265 uint32 bitsRead = 0;
1266 const uint8* data =
static_cast<const uint8*
> (buffer) + startBit / 8;
1268 if (
const uint32 offset = (startBit & 7))
1270 const uint32 bitsInByte = 8 - offset;
1271 result = (uint32) (*data >> offset);
1273 if (bitsInByte >= numBits)
1274 return result & ((1u << numBits) - 1u);
1276 numBits -= bitsInByte;
1277 bitsRead += bitsInByte;
1281 while (numBits >= 8)
1283 result |= (((uint32) *data++) << bitsRead);
1289 result |= ((*data & ((1u << numBits) - 1u)) << bitsRead);
1299class BigIntegerTests final :
public UnitTest
1303 : UnitTest (
"BigInteger", UnitTestCategories::maths)
1306 static BigInteger getBigRandom (Random& r)
1311 r.fillBitsRandomly (b, 0, r.nextInt (150) + 1);
1316 void runTest()
override
1319 beginTest (
"BigInteger");
1321 Random r = getRandom();
1323 expect (BigInteger().isZero());
1324 expect (BigInteger (1).isOne());
1326 for (
int j = 10000; --j >= 0;)
1328 BigInteger b1 (getBigRandom (r)),
1329 b2 (getBigRandom (r));
1331 BigInteger b3 = b1 + b2;
1332 expect (b3 > b1 && b3 > b2);
1333 expect (b3 - b1 == b2);
1334 expect (b3 - b2 == b1);
1336 BigInteger b4 = b1 * b2;
1337 expect (b4 > b1 && b4 > b2);
1338 expect (b4 / b1 == b2);
1339 expect (b4 / b2 == b1);
1340 expect (((b4 << 1) >> 1) == b4);
1341 expect (((b4 << 10) >> 10) == b4);
1342 expect (((b4 << 100) >> 100) == b4);
1347 b5.loadFromMemoryBlock (b3.toMemoryBlock());
1353 beginTest (
"Bit setting");
1355 Random r = getRandom();
1356 static uint8 test[2048];
1358 for (
int j = 100000; --j >= 0;)
1360 uint32 offset =
static_cast<uint32
> (r.nextInt (200) + 10);
1361 uint32 num =
static_cast<uint32
> (r.nextInt (32) + 1);
1362 uint32 value =
static_cast<uint32
> (r.nextInt());
1365 value &= ((1u << num) - 1);
1367 auto old1 = readLittleEndianBitsInBuffer (test, offset - 6, 6);
1368 auto old2 = readLittleEndianBitsInBuffer (test, offset + num, 6);
1369 writeLittleEndianBitsInBuffer (test, offset, num, value);
1370 auto result = readLittleEndianBitsInBuffer (test, offset, num);
1372 expect (result == value);
1373 expect (old1 == readLittleEndianBitsInBuffer (test, offset - 6, 6));
1374 expect (old2 == readLittleEndianBitsInBuffer (test, offset + num, 6));
1380static BigIntegerTests bigIntegerTests;
int size() const noexcept
void add(const ElementType &newElement)
ElementType & getReference(int index) noexcept
BigInteger & clear() noexcept
MemoryBlock toMemoryBlock() const
bool isOne() const noexcept
BigInteger getBitRange(int startBit, int numBits) const
void parseString(StringRef text, int base)
int64 toInt64() const noexcept
void exponentModulo(const BigInteger &exponent, const BigInteger &modulus)
void setNegative(bool shouldBeNegative) noexcept
uint32 getBitRangeAsInt(int startBit, int numBits) const noexcept
BigInteger & setRange(int startBit, int numBits, bool shouldBeSet)
BigInteger findGreatestCommonDivisor(BigInteger other) const
void extendedEuclidean(const BigInteger &a, const BigInteger &b, BigInteger &xOut, BigInteger &yOut)
int getHighestBit() const noexcept
void divideBy(const BigInteger &divisor, BigInteger &remainder)
String toString(int base, int minimumNumCharacters=1) const
BigInteger & shiftBits(int howManyBitsLeft, int startBit)
int findNextClearBit(int startIndex) const noexcept
int compare(const BigInteger &other) const noexcept
BigInteger & insertBit(int bitNumber, bool shouldBeSet)
BigInteger & setBitRangeAsInt(int startBit, int numBits, uint32 valueToSet)
BigInteger & clearBit(int bitNumber) noexcept
int findNextSetBit(int startIndex) const noexcept
void loadFromMemoryBlock(const MemoryBlock &data)
bool isZero() const noexcept
int countNumberOfSetBits() const noexcept
void swapWith(BigInteger &) noexcept
void montgomeryMultiplication(const BigInteger &other, const BigInteger &modulus, const BigInteger &modulusp, int k)
bool isNegative() const noexcept
bool operator[](int bit) const noexcept
int compareAbsolute(const BigInteger &other) const noexcept
BigInteger & operator=(BigInteger &&) noexcept
BigInteger & setBit(int bitNumber)
int toInteger() const noexcept
void inverseModulo(const BigInteger &modulus)
static constexpr uint32 littleEndianInt(const void *bytes) noexcept
static int getHexDigitValue(juce_wchar digit) noexcept
void calloc(SizeType newNumElements, const size_t elementSize=sizeof(ElementType))
void * getData() noexcept
size_t getSize() const noexcept
String::CharPointerType text
String paddedLeft(juce_wchar padCharacter, int minimumLength) const
static String charToString(juce_wchar character)