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; }
37 #if JUCE_GCC || JUCE_CLANG
40 unsigned long highest;
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),
105 highestBit (
other.getHighestBit()),
106 negative (
other.negative)
108 if (allocatedSize > numPreallocatedInts)
109 heapAllocation.
malloc (allocatedSize);
115 : heapAllocation (std::move (
other.heapAllocation)),
116 allocatedSize (
other.allocatedSize),
117 highestBit (
other.highestBit),
118 negative (
other.negative)
125 heapAllocation = std::move (
other.heapAllocation);
127 allocatedSize =
other.allocatedSize;
128 highestBit =
other.highestBit;
129 negative =
other.negative;
135 for (
int i = 0; i < numPreallocatedInts; ++i)
138 heapAllocation.swapWith (
other.heapAllocation);
148 highestBit =
other.getHighestBit();
152 heapAllocation.
free();
159 negative =
other.negative;
169 jassert (heapAllocation !=
nullptr || allocatedSize <= numPreallocatedInts);
171 return heapAllocation !=
nullptr ? heapAllocation
172 :
const_cast<uint32*
> (preallocated);
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)
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;
253 auto* values = getValues();
255 auto n = ((
uint32) values [pos]) >> offset;
258 n |= ((
uint32) values [pos + 1]) << (32 - offset);
271 for (
int i = 0; i <
numBits; ++i)
283 heapAllocation.
free();
284 allocatedSize = numPreallocatedInts;
288 for (
int i = 0; i < numPreallocatedInts; ++i)
298 if (bit > highestBit)
322 if (bit >= 0 && bit <= highestBit)
326 if (bit == highestBit)
327 highestBit = getHighestBit();
363 return negative && !
isZero();
373 negative = (! negative) && !
isZero();
376#if JUCE_MSVC && ! defined (__INTEL_COMPILER)
377 #pragma intrinsic (_BitScanReverse)
383 auto* values = getValues();
393 auto* values = getValues();
395 for (
int i = (
int)
bitToIndex (highestBit); i >= 0; --i)
404 auto* values = getValues();
406 for (; i <= highestBit; ++i)
415 auto* values = getValues();
417 for (; i <= highestBit; ++i)
430 if (
other.isNegative())
431 return operator-= (-
other);
451 highestBit =
jmax (highestBit,
other.highestBit) + 1;
454 auto* values = ensureSize (
numInts);
458 for (
size_t i = 0; i <
numInts; ++i)
462 if (i <
other.allocatedSize)
465 values[i] = (
uint32) remainder;
476BigInteger& BigInteger::operator-= (
const BigInteger&
other)
484 if (
other.isNegative())
485 return operator+= (-
other);
507 auto* values = getValues();
511 for (
size_t i = 0; i <
numInts; ++i)
533BigInteger& BigInteger::operator*= (
const BigInteger&
other)
539 auto t =
other.getHighestBit();
545 total.highestBit = n + t + 1;
552 m.setNegative (
false);
555 auto* values = getValues();
557 for (
int i = 0; i <= t; ++i)
561 for (
int j = 0;
j <= n; ++
j)
608 while (leftShift >= 0)
610 if (
remainder.compareAbsolute (temp) >= 0)
616 if (--leftShift >= 0)
632BigInteger& BigInteger::operator|= (
const BigInteger&
other)
640 if (
other.highestBit >= 0)
650 if (
other.highestBit > highestBit)
651 highestBit =
other.highestBit;
659BigInteger& BigInteger::operator&= (
const BigInteger&
other)
667 auto* values = getValues();
670 auto n = (
int) allocatedSize;
672 while (n > (
int)
other.allocatedSize)
678 if (
other.highestBit < highestBit)
679 highestBit =
other.highestBit;
685BigInteger& BigInteger::operator^= (
const BigInteger&
other)
696 if (
other.highestBit >= 0)
706 if (
other.highestBit > highestBit)
707 highestBit =
other.highestBit;
715BigInteger& BigInteger::operator%= (
const BigInteger&
divisor)
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; }
745 auto isNeg = isNegative();
753 return isNeg ? -1 : 1;
758 auto h1 = getHighestBit();
759 auto h2 =
other.getHighestBit();
761 if (
h1 >
h2)
return 1;
762 if (
h1 <
h2)
return -1;
764 auto* values = getValues();
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]);
815 values[i] = (values[i] << bits) | (values[i - 1] >>
invBits);
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)
844 auto* values = getValues();
848 for (
size_t i = 0; i < top; ++i)
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);
907 return simpleGCD (&m, &n);
928 auto n =
exp.getHighestBit();
930 for (
int i = n; --i >= 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;)
979 xm.montgomeryMultiplication (1, modulus,
m1,
Rfactor);
991 setRange (k, highestBit - k + 1,
false);
994 setRange (k, highestBit - k + 1,
false);
1011 while (! q.isZero())
1032 if (gcd.compareAbsolute (y * b - x * a) != 0)
1063 b1 (modulus),
b2 (1);
1065 while (!
a2.isOne())
1085 while (
b2.isNegative())
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);
1119 else if (base == 10)
1152 if (base == 2 || base == 8 || base == 16)
1154 auto bits = (base == 2) ? 1 : (base == 8 ? 3 : 4);
1158 auto c = t.getAndAdvance();
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();
1209 auto* values = ensureSize (
numInts);
1216 for (
int i = (
int) (numBytes & ~3u); i < (
int) numBytes; ++i)
1219 highestBit = (
int) numBytes * 8;
1235 const uint8 current = *data;
1239 *data = (
uint8) ((current & ~(((1u <<
numBits) - 1u) << offset)) | (value << offset));
1243 *data++ = current ^ (
uint8) (((value << offset) ^ current) & (((1u <<
bitsInByte) - 1u) << offset));
1250 *data++ = (
uint8) value;
1271 result = (
uint32) (*data >> offset);
1274 return result & ((1u <<
numBits) - 1u);
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;)
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);
1365 value &= ((1u << num) - 1);
1372 expect (result == value);
Holds a resizable array of primitive or copy-by-value objects.
void add(const ElementType &newElement)
Appends a new element at the end of the array.
An arbitrarily large integer class.
BigInteger & clear() noexcept
Resets the value to 0.
MemoryBlock toMemoryBlock() const
Turns the number into a block of binary data.
bool isOne() const noexcept
Returns true if the value is 1.
BigInteger getBitRange(int startBit, int numBits) const
Returns a range of bits as a new BigInteger.
void parseString(StringRef text, int base)
Reads the numeric value from a string.
int64 toInt64() const noexcept
Attempts to get the lowest 64 bits of the value as an integer.
void exponentModulo(const BigInteger &exponent, const BigInteger &modulus)
Performs a combined exponent and modulo operation.
void setNegative(bool shouldBeNegative) noexcept
Changes the sign of the number to be positive or negative.
uint32 getBitRangeAsInt(int startBit, int numBits) const noexcept
Returns a range of bits as an integer value.
BigInteger & setRange(int startBit, int numBits, bool shouldBeSet)
Sets a range of bits to be either on or off.
BigInteger findGreatestCommonDivisor(BigInteger other) const
Returns the largest value that will divide both this value and the argument.
void extendedEuclidean(const BigInteger &a, const BigInteger &b, BigInteger &xOut, BigInteger &yOut)
Performs the Extended Euclidean algorithm.
int getHighestBit() const noexcept
Returns the index of the highest set bit in the number.
void divideBy(const BigInteger &divisor, BigInteger &remainder)
Divides this value by another one and returns the remainder.
String toString(int base, int minimumNumCharacters=1) const
Converts the number to a string.
BigInteger & shiftBits(int howManyBitsLeft, int startBit)
Shifts a section of bits left or right.
int findNextClearBit(int startIndex) const noexcept
Looks for the index of the next clear bit after a given starting point.
int compare(const BigInteger &other) const noexcept
Does a signed comparison of two BigIntegers.
BigInteger & insertBit(int bitNumber, bool shouldBeSet)
Inserts a bit an a given position, shifting up any bits above it.
BigInteger & setBitRangeAsInt(int startBit, int numBits, uint32 valueToSet)
Sets a range of bits to an integer value.
BigInteger & clearBit(int bitNumber) noexcept
Clears a particular bit in the number.
BigInteger()
Creates an empty BigInteger.
void negate() noexcept
Inverts the sign of the number.
int findNextSetBit(int startIndex) const noexcept
Looks for the index of the next set bit after a given starting point.
void loadFromMemoryBlock(const MemoryBlock &data)
Converts a block of raw data into a number.
bool isZero() const noexcept
Returns true if no bits are set.
int countNumberOfSetBits() const noexcept
Returns the total number of set bits in the value.
void swapWith(BigInteger &) noexcept
Swaps the internal contents of this with another object.
void montgomeryMultiplication(const BigInteger &other, const BigInteger &modulus, const BigInteger &modulusp, int k)
Performs the Montgomery Multiplication with modulo.
bool isNegative() const noexcept
Returns true if the value is less than zero.
bool operator[](int bit) const noexcept
Returns the value of a specified bit in the number.
int compareAbsolute(const BigInteger &other) const noexcept
Compares the magnitudes of two BigIntegers, ignoring their signs.
BigInteger & operator=(BigInteger &&) noexcept
Move assignment operator.
BigInteger & setBit(int bitNumber)
Sets a specified bit to 1.
int toInteger() const noexcept
Attempts to get the lowest 32 bits of the value as an integer.
void inverseModulo(const BigInteger &modulus)
Performs an inverse modulo on the value.
static constexpr uint32 littleEndianInt(const void *bytes) noexcept
Turns 4 bytes into a little-endian integer.
CharPointer_UTF8 findEndOfWhitespace() const noexcept
Returns the first non-whitespace character in the string.
static int getHexDigitValue(juce_wchar digit) noexcept
Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legal hex digit.
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Allocates a specified amount of memory.
void realloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Re-allocates a specified amount of memory.
void free() noexcept
Frees any currently-allocated data.
void calloc(SizeType newNumElements, const size_t elementSize=sizeof(ElementType))
Allocates a specified amount of memory and clears it.
A class to hold a resizable block of raw data.
The base class for streams that write data to some kind of destination.
A simple class for holding temporary references to a string literal or String.
String::CharPointerType text
The text that is referenced.
String paddedLeft(juce_wchar padCharacter, int minimumLength) const
Returns a copy of this string with the specified character repeatedly added to its beginning until th...
static String charToString(juce_wchar character)
Creates a string from a single character.
uint32 readLittleEndianBitsInBuffer(const void *buffer, uint32 startBit, uint32 numBits) noexcept
Reads a number of bits from a buffer at a given bit index.
wchar_t juce_wchar
A platform-independent 32-bit unicode character type.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
int findHighestSetBit(uint32 n) noexcept
Returns the index of the highest set bit in a (non-zero) number.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
signed int int32
A platform-independent 32-bit signed integer type.
void writeLittleEndianBitsInBuffer(void *buffer, uint32 startBit, uint32 numBits, uint32 value) noexcept
Writes a number of bits into a memory buffer at a given bit index.
constexpr int countNumberOfBits(uint32 n) noexcept
Returns the number of bits in a 32-bit integer.
OutputStream &JUCE_CALLTYPE operator<<(OutputStream &stream, const BigInteger &value)
Writes a BigInteger to an OutputStream as a UTF8 decimal string.
unsigned long long uint64
A platform-independent 64-bit unsigned integer type.
Type * addBytesToPointer(Type *basePointer, IntegerType bytes) noexcept
A handy function which adds a number of bytes to any type of pointer and returns the result.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
long long int64
A platform-independent 64-bit integer type.