|
@@ -1,20 +1,26 @@
|
|
|
#include <vector>
|
|
|
#include <algorithm>
|
|
|
#include <cstring>
|
|
|
+#include <random>
|
|
|
#include <iterator>
|
|
|
#include <stdexcept>
|
|
|
#include <cstdint>
|
|
|
#include <cassert>
|
|
|
using std::uint64_t;
|
|
|
+static uint64_t bitsPerDigit[] = { 0, 0,
|
|
|
+ 1024, 1624, 2048, 2378, 2648, 2875, 3072, 3247, 3402, 3543, 3672,
|
|
|
+ 3790, 3899, 4001, 4096, 4186, 4271, 4350, 4426, 4498, 4567, 4633,
|
|
|
+ 4696, 4756, 4814, 4870, 4923, 4975, 5025, 5074, 5120, 5166, 5210,
|
|
|
+ 5253, 5295};
|
|
|
class BigInteger{
|
|
|
- const int signum;
|
|
|
+ int signum;
|
|
|
std::vector<int> mag;
|
|
|
int bitCount;
|
|
|
int bitLength;
|
|
|
int lowestSetBit;
|
|
|
int firstNonzeroIntNum;
|
|
|
const static uint64_t LONG_MASK = 0xffffffffL;
|
|
|
- static const int MAX_MAG_LENGTH = Integer.MAX_VALUE / Integer.SIZE + 1; // (1 << 26)
|
|
|
+ static const int MAX_MAG_LENGTH = (1 << 26);
|
|
|
static const int PRIME_SEARCH_BIT_LENGTH_LIMIT = 500000000;
|
|
|
static const int KARATSUBA_THRESHOLD = 80;
|
|
|
static const int TOOM_COOK_THRESHOLD = 240;
|
|
@@ -32,7 +38,7 @@ class BigInteger{
|
|
|
signum = -1;
|
|
|
} else {
|
|
|
mag = stripLeadingZeroBytes(val);
|
|
|
- signum = (mag.length == 0 ? 0 : 1);
|
|
|
+ signum = (mag.size() == 0 ? 0 : 1);
|
|
|
}
|
|
|
if (mag.size() >= MAX_MAG_LENGTH) {
|
|
|
checkRange();
|
|
@@ -72,19 +78,19 @@ class BigInteger{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ BigInteger():BigInteger((int)0){}
|
|
|
BigInteger(int signum, std::vector<int> magnitude) {
|
|
|
mag = stripLeadingZeroInts(magnitude);
|
|
|
|
|
|
assert(!(signum < -1 || signum > 1));
|
|
|
|
|
|
- if (this.mag.length == 0) {
|
|
|
+ if (this.mag.size() == 0) {
|
|
|
signum = 0;
|
|
|
} else {
|
|
|
assert(signum != 0);
|
|
|
signum = signum;
|
|
|
}
|
|
|
- if (mag.length >= MAX_MAG_LENGTH) {
|
|
|
+ if (mag.size() >= MAX_MAG_LENGTH) {
|
|
|
checkRange();
|
|
|
}
|
|
|
}
|
|
@@ -135,7 +141,7 @@ class BigInteger{
|
|
|
destructiveMulAdd(magnitude, intRadix[10], groupVal);
|
|
|
}
|
|
|
mag = trustedStripLeadingZeroInts(magnitude);
|
|
|
- if (mag.length >= MAX_MAG_LENGTH) {
|
|
|
+ if (mag.size() >= MAX_MAG_LENGTH) {
|
|
|
checkRange();
|
|
|
}
|
|
|
}
|
|
@@ -159,18 +165,14 @@ class BigInteger{
|
|
|
|
|
|
// bitsPerDigit in the given radix times 1024
|
|
|
// Rounded up to avoid underallocation.
|
|
|
- static uint64_t bitsPerDigit[] = { 0, 0,
|
|
|
- 1024, 1624, 2048, 2378, 2648, 2875, 3072, 3247, 3402, 3543, 3672,
|
|
|
- 3790, 3899, 4001, 4096, 4186, 4271, 4350, 4426, 4498, 4567, 4633,
|
|
|
- 4696, 4756, 4814, 4870, 4923, 4975, 5025, 5074, 5120, 5166, 5210,
|
|
|
- 5253, 5295};
|
|
|
+
|
|
|
|
|
|
// Multiply x array times word y in place, and add word z
|
|
|
static void destructiveMulAdd(std::vector<int>& x, int y, int z) {
|
|
|
// Perform the multiplication word by word
|
|
|
uint64_t ylong = y & LONG_MASK;
|
|
|
uint64_t zlong = z & LONG_MASK;
|
|
|
- int len = x.length;
|
|
|
+ int len = x.size();
|
|
|
|
|
|
uint64_t product = 0;
|
|
|
uint64_t carry = 0;
|
|
@@ -403,7 +405,7 @@ class BigInteger{
|
|
|
}
|
|
|
|
|
|
|
|
|
- boolean passesLucasLehmer() {
|
|
|
+ bool passesLucasLehmer() {
|
|
|
BigInteger thisPlusOne = this->add(ONE);
|
|
|
|
|
|
// Step 1
|
|
@@ -427,7 +429,7 @@ class BigInteger{
|
|
|
|
|
|
// Algorithm and comments adapted from Colin Plumb's C library.
|
|
|
int j = 1;
|
|
|
- int u = n.mag[n.mag.length-1];
|
|
|
+ int u = n.mag[n.mag.size()-1];
|
|
|
|
|
|
// Make p positive
|
|
|
if (p < 0) {
|
|
@@ -535,26 +537,26 @@ class BigInteger{
|
|
|
}
|
|
|
|
|
|
|
|
|
- BigInteger(const std::vector<int> magnitude&, int signum) {
|
|
|
- this.signum = (magnitude.siz() == 0 ? 0 : signum);
|
|
|
+ BigInteger(const std::vector<int>& magnitude, int signum) {
|
|
|
+ this.signum = (magnitude.size() == 0 ? 0 : signum);
|
|
|
this.mag = magnitude;
|
|
|
- if (mag.length >= MAX_MAG_LENGTH) {
|
|
|
+ if (mag.size() >= MAX_MAG_LENGTH) {
|
|
|
checkRange();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
- BigInteger(const std::vector<int> magnitude&e, int signum) {
|
|
|
- signum = (magnitude.length == 0 ? 0 : signum);
|
|
|
+ BigInteger(const std::vector<int>& magnitude, int signum) {
|
|
|
+ signum = (magnitude.size() == 0 ? 0 : signum);
|
|
|
mag = stripLeadingZeroBytes(magnitude);
|
|
|
- if (mag.length >= MAX_MAG_LENGTH) {
|
|
|
+ if (mag.size() >= MAX_MAG_LENGTH) {
|
|
|
checkRange();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void checkRange() {
|
|
|
- if (mag.length > MAX_MAG_LENGTH || mag.length == MAX_MAG_LENGTH && mag[0] < 0) {
|
|
|
+ if (mag.size() > MAX_MAG_LENGTH || mag.size() == MAX_MAG_LENGTH && mag[0] < 0) {
|
|
|
reportOverflow();
|
|
|
}
|
|
|
}
|
|
@@ -618,7 +620,7 @@ class BigInteger{
|
|
|
static const double[] logCache;
|
|
|
|
|
|
|
|
|
- static const double LOG_TWO = Math.log(2.0);
|
|
|
+ static const double LOG_TWO = std::log(2.0);
|
|
|
|
|
|
static void initStuff(){
|
|
|
for (int i = 1; i <= MAX_CONSTANT; i++) {
|
|
@@ -704,7 +706,7 @@ class BigInteger{
|
|
|
long sum = 0;
|
|
|
int xIndex = x.size();
|
|
|
std::vector<int> result;
|
|
|
- int highWord = (int)(val >>> 32);
|
|
|
+ int highWord = (int)(val >> 32);
|
|
|
if (highWord == 0) {
|
|
|
result = std::vector<int>(xIndex);
|
|
|
sum = (x[--xIndex] & LONG_MASK) + val;
|
|
@@ -733,7 +735,7 @@ class BigInteger{
|
|
|
result[--xIndex] = x[xIndex];
|
|
|
// Grow result if necessary
|
|
|
if (carry) {
|
|
|
- std::vector<int> bigger(result.length + 1);
|
|
|
+ std::vector<int> bigger(result.size() + 1);
|
|
|
//System.arraycopy(result, 0, bigger, 1, result.length);
|
|
|
std::copy(result.begin(),result.end(), bigger.begin());
|
|
|
bigger[0] = 0x01;
|
|
@@ -752,8 +754,8 @@ class BigInteger{
|
|
|
y = tmp;*/
|
|
|
}
|
|
|
|
|
|
- int xIndex = x.length;
|
|
|
- int yIndex = y.length;
|
|
|
+ int xIndex = x.size();
|
|
|
+ int yIndex = y.size();
|
|
|
std::vector<int> result(xIndex);// = new int[xIndex];
|
|
|
long sum = 0;
|
|
|
if (yIndex == 1) {
|
|
@@ -768,7 +770,7 @@ class BigInteger{
|
|
|
}
|
|
|
}
|
|
|
// Copy remainder of longer number while carry propagation is required
|
|
|
- boolean carry = (sum >>> 32 != 0);
|
|
|
+ bool carry = (sum >>> 32 != 0);
|
|
|
while (xIndex > 0 && carry)
|
|
|
carry = ((result[--xIndex] = x[xIndex] + 1) == 0);
|
|
|
|
|
@@ -778,7 +780,7 @@ class BigInteger{
|
|
|
|
|
|
// Grow result if necessary
|
|
|
if (carry) {
|
|
|
- std::vector<int> bigger(result.length + 1);
|
|
|
+ std::vector<int> bigger(result.size() + 1);
|
|
|
std::copy(result.begin(),result.end(),bigger.begin());
|
|
|
bigger[0] = 0x01;
|
|
|
return bigger;
|
|
@@ -786,15 +788,15 @@ class BigInteger{
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- static int[] subtract(std::int64_t val, int[] little) {
|
|
|
+ static std::vector<int> subtract(std::int64_t val, std::vector<int> little) {
|
|
|
int highWord = (int)(((uint64_t)val) >> 32);
|
|
|
if (highWord == 0) {
|
|
|
- std::vector<int>result(1);
|
|
|
+ std::vector<int> result(1);
|
|
|
result[0] = (int)(val - (little[0] & LONG_MASK));
|
|
|
return result;
|
|
|
} else {
|
|
|
std::vector<int> result(2);
|
|
|
- if (little.length == 1) {
|
|
|
+ if (little.size() == 1) {
|
|
|
std::int64_t difference = ((int)val & LONG_MASK) - (little[0] & LONG_MASK);
|
|
|
result[1] = (int)difference;
|
|
|
// Subtract remainder of longer number while borrow propagates
|
|
@@ -833,7 +835,7 @@ class BigInteger{
|
|
|
}
|
|
|
|
|
|
// Subtract remainder of longer number while borrow propagates
|
|
|
- boolean borrow = (difference >> 32 != 0);
|
|
|
+ bool borrow = (difference >> 32 != 0);
|
|
|
while (bigIndex > 0 && borrow)
|
|
|
borrow = ((result[--bigIndex] = big[bigIndex] - 1) == -1);
|
|
|
|
|
@@ -927,11 +929,11 @@ class BigInteger{
|
|
|
if (__builtin_popcount(y) == 1) {
|
|
|
return BigInteger(shiftLeft(x,__builtin_ctz(y)), sign);
|
|
|
}
|
|
|
- int xlen = x.length;
|
|
|
+ int xlen = x.size();
|
|
|
std::vector<int> rmag(xlen + 1);
|
|
|
long carry = 0;
|
|
|
long yl = y & LONG_MASK;
|
|
|
- int rstart = rmag.length - 1;
|
|
|
+ int rstart = rmag.size() - 1;
|
|
|
for (int i = xlen - 1; i >= 0; i--) {
|
|
|
std::uint64_t product = (x[i] & LONG_MASK) * yl + carry;
|
|
|
rmag[rstart--] = (int)product;
|
|
@@ -957,11 +959,11 @@ class BigInteger{
|
|
|
uint64_t dh = v >> 32; // higher order bits
|
|
|
uint64_t dl = v & LONG_MASK; // lower order bits
|
|
|
|
|
|
- int xlen = mag.length;
|
|
|
+ int xlen = mag.size();
|
|
|
std::vector<int> value = mag;
|
|
|
std::vector<int> rmag = (dh == 0L) ? (std::vector<int>([xlen + 1])) : (std::vector<int>([xlen + 2]));
|
|
|
uint64_t carry = 0;
|
|
|
- int rstart = rmag.length - 1;
|
|
|
+ int rstart = rmag.size() - 1;
|
|
|
for (int i = xlen - 1; i >= 0; i--) {
|
|
|
uint64_t product = (value[i] & LONG_MASK) * dl + carry;
|
|
|
rmag[rstart--] = (int)product;
|
|
@@ -970,7 +972,7 @@ class BigInteger{
|
|
|
rmag[rstart] = (int)carry;
|
|
|
if (dh != 0L) {
|
|
|
carry = 0;
|
|
|
- rstart = rmag.length - 2;
|
|
|
+ rstart = rmag.size() - 2;
|
|
|
for (int i = xlen - 1; i >= 0; i--) {
|
|
|
long product = (value[i] & LONG_MASK) * dh +
|
|
|
(rmag[rstart] & LONG_MASK) + carry;
|
|
@@ -989,7 +991,7 @@ class BigInteger{
|
|
|
int xstart = xlen - 1;
|
|
|
int ystart = ylen - 1;
|
|
|
|
|
|
- if (z.length < (xlen+ ylen))
|
|
|
+ if (z.size() < (xlen+ ylen))
|
|
|
z = std::vector<int>(xlen+ylen);
|
|
|
|
|
|
uint64_t carry = 0;
|
|
@@ -1199,7 +1201,7 @@ class BigInteger{
|
|
|
|
|
|
|
|
|
BigInteger getUpper(int n) {
|
|
|
- int len = mag.length;
|
|
|
+ int len = mag.size();
|
|
|
|
|
|
if (len <= n) {
|
|
|
return ZERO;
|
|
@@ -1236,7 +1238,7 @@ class BigInteger{
|
|
|
|
|
|
static std::vector<int> squareToLen(std::vector<int> x, int len, std::vector<int> z) {
|
|
|
int zlen = len << 1;
|
|
|
- if (z == null || z.length < zlen)
|
|
|
+ if (z == null || z.size() < zlen)
|
|
|
z = std::vector<int>(zlen);
|
|
|
|
|
|
// Execute checks before calling intrinsified method.
|
|
@@ -1391,8 +1393,8 @@ class BigInteger{
|
|
|
|
|
|
|
|
|
BigInteger divide(BigInteger val) {
|
|
|
- if (val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD ||
|
|
|
- mag.length - val.mag.length < BURNIKEL_ZIEGLER_OFFSET) {
|
|
|
+ if (val.mag.size() < BURNIKEL_ZIEGLER_THRESHOLD ||
|
|
|
+ mag.size() - val.mag.size() < BURNIKEL_ZIEGLER_OFFSET) {
|
|
|
return divideKnuth(val);
|
|
|
} else {
|
|
|
return divideBurnikelZiegler(val);
|
|
@@ -1411,8 +1413,8 @@ class BigInteger{
|
|
|
|
|
|
|
|
|
std::vector<BigInteger> divideAndRemainder(BigInteger val) {
|
|
|
- if (val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD ||
|
|
|
- mag.length - val.mag.length < BURNIKEL_ZIEGLER_OFFSET) {
|
|
|
+ if (val.mag.size() < BURNIKEL_ZIEGLER_THRESHOLD ||
|
|
|
+ mag.size() - val.mag.size() < BURNIKEL_ZIEGLER_OFFSET) {
|
|
|
return divideAndRemainderKnuth(val);
|
|
|
} else {
|
|
|
return divideAndRemainderBurnikelZiegler(val);
|
|
@@ -1434,7 +1436,7 @@ class BigInteger{
|
|
|
|
|
|
BigInteger remainder(BigInteger val) {
|
|
|
if (val.mag.size() < BURNIKEL_ZIEGLER_THRESHOLD ||
|
|
|
- mag.size() - val.mag.length < BURNIKEL_ZIEGLER_OFFSET) {
|
|
|
+ mag.size() - val.mag.size() < BURNIKEL_ZIEGLER_OFFSET) {
|
|
|
return remainderKnuth(val);
|
|
|
} else {
|
|
|
return remainderBurnikelZiegler(val);
|
|
@@ -1614,12 +1616,12 @@ class BigInteger{
|
|
|
if (nBits <= (32 - bitsInHighWord)) {
|
|
|
std::vector<int> result(nInts + len);
|
|
|
std::copy(a.begin(),a.begin() + len, result.begin());
|
|
|
- primitiveLeftShift(result, result.length, nBits);
|
|
|
+ primitiveLeftShift(result, result.size(), nBits);
|
|
|
return result;
|
|
|
} else {
|
|
|
std::vector<int> resul(nInts + len + 1);
|
|
|
std::copy(a.begin(), a.begin() + len, result.begin());
|
|
|
- primitiveRightShift(result, result.length, 32 - nBits);
|
|
|
+ primitiveRightShift(result, result.size(), 32 - nBits);
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
@@ -1667,11 +1669,6 @@ class BigInteger{
|
|
|
return BigInteger(this->mag, -this->signum);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- int signum() {
|
|
|
- return this->signum;
|
|
|
- }
|
|
|
-
|
|
|
// Modular Arithmetic Operations
|
|
|
|
|
|
|
|
@@ -1699,7 +1696,7 @@ class BigInteger{
|
|
|
if (this.equals(negConst[1]) && (!exponent.testBit(0)))
|
|
|
return (m.equals(ONE) ? ZERO : ONE);
|
|
|
|
|
|
- boolean invertResult;
|
|
|
+ bool invertResult;
|
|
|
if ((invertResult = (exponent.signum < 0)))
|
|
|
exponent = exponent.negate();
|
|
|
|
|
@@ -1736,7 +1733,7 @@ class BigInteger{
|
|
|
BigInteger y1 = m2.modInverse(m1);
|
|
|
BigInteger y2 = m1.modInverse(m2);
|
|
|
|
|
|
- if (m.mag.length < MAX_MAG_LENGTH / 2) {
|
|
|
+ if (m.mag.size() < MAX_MAG_LENGTH / 2) {
|
|
|
result = a1.multiply(m2).multiply(y1).add(a2.multiply(m1).multiply(y2)).mod(m);
|
|
|
} else {
|
|
|
MutableBigInteger t1;
|
|
@@ -1931,7 +1928,7 @@ class BigInteger{
|
|
|
std::int64_t inv = -MutableBigInteger.inverseMod64(n0);
|
|
|
|
|
|
// Convert base to Montgomery form
|
|
|
- std::vector<int> a = leftShift(base, base.length, modLen << 5);
|
|
|
+ std::vector<int> a = leftShift(base, base.size(), modLen << 5);
|
|
|
|
|
|
MutableBigInteger q = MutableBigInteger(),
|
|
|
a2 = MutableBigInteger(a),
|
|
@@ -2064,7 +2061,7 @@ class BigInteger{
|
|
|
int offset = 0;
|
|
|
|
|
|
do {
|
|
|
- int nEnd = n[n.length-1-offset];
|
|
|
+ int nEnd = n[n.size()-1-offset];
|
|
|
int carry = mulAdd(n, mod, offset, mlen, inv * nEnd);
|
|
|
c += addOne(n, offset, mlen, carry);
|
|
|
offset++;
|
|
@@ -2123,11 +2120,11 @@ class BigInteger{
|
|
|
if (offset < 0) {
|
|
|
throw std::invalid_argument("input offset is invalid: " + std::to_string(offset));
|
|
|
}
|
|
|
- if (offset > (out.length - 1)) {
|
|
|
- throw std::invalid_argument("input offset is out of bound: " + std::to_string(offset) + " > " + std::to_string(out.length - 1));
|
|
|
+ if (offset > (out.size() - 1)) {
|
|
|
+ throw std::invalid_argument("input offset is out of bound: " + std::to_string(offset) + " > " + std::to_string(out.size() - 1));
|
|
|
}
|
|
|
- if (len > (out.length - offset)) {
|
|
|
- throw std::invalid_argument("input len is out of bound: " + std::to_string(len) + " > " + std::to_string(out.length - offset));
|
|
|
+ if (len > (out.size() - offset)) {
|
|
|
+ throw std::invalid_argument("input len is out of bound: " + std::to_string(len) + " > " + std::to_string(out.size() - offset));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2136,7 +2133,7 @@ class BigInteger{
|
|
|
std::int64_t kLong = k & LONG_MASK;
|
|
|
std::int64_t carry = 0;
|
|
|
|
|
|
- offset = out.length-offset - 1;
|
|
|
+ offset = out.size()-offset - 1;
|
|
|
for (int j=len-1; j >= 0; j--) {
|
|
|
std::uint64_t product = (in[j] & LONG_MASK) * kLong +
|
|
|
(out[offset] & LONG_MASK) + carry;
|
|
@@ -2148,7 +2145,7 @@ class BigInteger{
|
|
|
|
|
|
|
|
|
static int addOne(std::vector<int> a, int offset, int mlen, int carry) {
|
|
|
- offset = a.length-1-mlen-offset;
|
|
|
+ offset = a.size()-1-mlen-offset;
|
|
|
std::uint64_t t = (a[offset] & LONG_MASK) + (carry & LONG_MASK);
|
|
|
|
|
|
a[offset] = (int)t;
|
|
@@ -2200,7 +2197,7 @@ class BigInteger{
|
|
|
// Copy remaining ints of mag
|
|
|
int numInts = (p + 31) >> 5;
|
|
|
std::vector<int> mag(numInts,0);
|
|
|
- System.arraycopy(this.mag, (this.mag.length - numInts), mag, 0, numInts);
|
|
|
+ System.arraycopy(this->mag, (this->mag.size() - numInts), mag, 0, numInts);
|
|
|
|
|
|
// Mask out any excess bits
|
|
|
int excessBits = (numInts << 5) - p;
|
|
@@ -2337,10 +2334,10 @@ class BigInteger{
|
|
|
|
|
|
std::vector<int> javaIncrement(std::vector<int> val) {
|
|
|
int lastSum = 0;
|
|
|
- for (int i=val.length-1; i >= 0 && lastSum == 0; i--)
|
|
|
+ for (int i=val.size()-1; i >= 0 && lastSum == 0; i--)
|
|
|
lastSum = (val[i] += 1);
|
|
|
if (lastSum == 0) {
|
|
|
- val = std::vector<int>(val.length+1);
|
|
|
+ val = std::vector<int>(val.size()+1);
|
|
|
val[0] = 1;
|
|
|
}
|
|
|
return val;
|
|
@@ -2351,9 +2348,9 @@ class BigInteger{
|
|
|
|
|
|
BigInteger and(BigInteger val) {
|
|
|
std::vector<int> result(std::max(intLength(), val.intLength()));
|
|
|
- for (int i=0; i < result.length; i++)
|
|
|
- result[i] = (getInt(result.length-i-1)
|
|
|
- & val.getInt(result.length-i-1));
|
|
|
+ for (int i=0; i < result.size(); i++)
|
|
|
+ result[i] = (getInt(result.size()-i-1)
|
|
|
+ & val.getInt(result.size()-i-1));
|
|
|
|
|
|
return valueOf(result);
|
|
|
}
|
|
@@ -2361,9 +2358,9 @@ class BigInteger{
|
|
|
|
|
|
BigInteger or(BigInteger val) {
|
|
|
std::vector<int> result(std::max(intLength(), val.intLength()));
|
|
|
- for (int i=0; i < result.length; i++)
|
|
|
- result[i] = (getInt(result.length-i-1)
|
|
|
- | val.getInt(result.length-i-1));
|
|
|
+ for (int i=0; i < result.size(); i++)
|
|
|
+ result[i] = (getInt(result.size()-i-1)
|
|
|
+ | val.getInt(result.size()-i-1));
|
|
|
|
|
|
return valueOf(result);
|
|
|
}
|
|
@@ -2371,9 +2368,9 @@ class BigInteger{
|
|
|
|
|
|
BigInteger xor(BigInteger val) {
|
|
|
std::vector<int> result(std::max(intLength(), val.intLength()));
|
|
|
- for (int i=0; i < result.length; i++)
|
|
|
- result[i] = (getInt(result.length-i-1)
|
|
|
- ^ val.getInt(result.length-i-1));
|
|
|
+ for (int i=0; i < result.size(); i++)
|
|
|
+ result[i] = (getInt(result.size()-i-1)
|
|
|
+ ^ val.getInt(result.size()-i-1));
|
|
|
|
|
|
return valueOf(result);
|
|
|
}
|
|
@@ -2381,17 +2378,17 @@ class BigInteger{
|
|
|
|
|
|
BigInteger not() {
|
|
|
std::vector<int> result(intLength());
|
|
|
- for (int i=0; i < result.length; i++)
|
|
|
- result[i] = ~getInt(result.length-i-1);
|
|
|
+ for (int i=0; i < result.size(); i++)
|
|
|
+ result[i] = ~getInt(result.size()-i-1);
|
|
|
return valueOf(result);
|
|
|
}
|
|
|
|
|
|
|
|
|
BigInteger andNot(BigInteger val) {
|
|
|
std::vector<int> result(std::max(intLength(), val.intLength()));
|
|
|
- for (int i=0; i < result.length; i++)
|
|
|
- result[i] = (getInt(result.length-i-1)
|
|
|
- & ~val.getInt(result.length-i-1));
|
|
|
+ for (int i=0; i < result.size(); i++)
|
|
|
+ result[i] = (getInt(result.size()-i-1)
|
|
|
+ & ~val.getInt(result.size()-i-1));
|
|
|
|
|
|
return valueOf(result);
|
|
|
}
|
|
@@ -2407,13 +2404,13 @@ class BigInteger{
|
|
|
|
|
|
BigInteger setBit(unsigned int n) {
|
|
|
|
|
|
- int intNum = n >>> 5;
|
|
|
+ int intNum = n >> 5;
|
|
|
std::vector<int> result(std::max(intLength(), intNum+2));
|
|
|
|
|
|
- for (int i=0; i < result.length; i++)
|
|
|
- result[result.length-i-1] = getInt(i);
|
|
|
+ for (int i=0; i < result.size(); i++)
|
|
|
+ result[result.size()-i-1] = getInt(i);
|
|
|
|
|
|
- result[result.length-intNum-1] |= (1 << (n & 31));
|
|
|
+ result[result.size()-intNum-1] |= (1 << (n & 31));
|
|
|
|
|
|
return valueOf(result);
|
|
|
}
|
|
@@ -2422,10 +2419,10 @@ class BigInteger{
|
|
|
int intNum = n >> 5;
|
|
|
std::vector<int> result(std::max(intLength(), ((n + 1) >> 5) + 1));
|
|
|
|
|
|
- for (int i=0; i < result.length; i++)
|
|
|
- result[result.length-i-1] = getInt(i);
|
|
|
+ for (int i=0; i < result.size(); i++)
|
|
|
+ result[result.size()-i-1] = getInt(i);
|
|
|
|
|
|
- result[result.length-intNum-1] &= ~(1 << (n & 31));
|
|
|
+ result[result.size()-intNum-1] &= ~(1 << (n & 31));
|
|
|
return valueOf(result);
|
|
|
}
|
|
|
|
|
@@ -2435,10 +2432,10 @@ class BigInteger{
|
|
|
int intNum = n >> 5;
|
|
|
std::vector<int> result(std::max(intLength(), intNum+2));
|
|
|
|
|
|
- for (int i=0; i < result.length; i++)
|
|
|
- result[result.length-i-1] = getInt(i);
|
|
|
+ for (int i=0; i < result.size(); i++)
|
|
|
+ result[result.size()-i-1] = getInt(i);
|
|
|
|
|
|
- result[result.length-intNum-1] ^= (1 << (n & 31));
|
|
|
+ result[result.size()-intNum-1] ^= (1 << (n & 31));
|
|
|
|
|
|
return valueOf(result);
|
|
|
}
|
|
@@ -2500,7 +2497,7 @@ class BigInteger{
|
|
|
if (signum < 0) {
|
|
|
// Count the trailing zeros in the magnitude
|
|
|
int magTrailingZeroCount = 0, j;
|
|
|
- for (j=mag.length-1; mag[j] == 0; j--)
|
|
|
+ for (j=mag.size()-1; mag[j] == 0; j--)
|
|
|
magTrailingZeroCount += 32;
|
|
|
magTrailingZeroCount += __builtin_ctz(mag[j]);
|
|
|
bc += magTrailingZeroCount - 1;
|
|
@@ -2545,9 +2542,9 @@ class BigInteger{
|
|
|
|
|
|
const int compareMagnitude(BigInteger val) {
|
|
|
std::vector<int> m1 = mag;
|
|
|
- int len1 = m1.length;
|
|
|
+ int len1 = m1.size();
|
|
|
std::vector<int> m2 = val.mag;
|
|
|
- int len2 = m2.length;
|
|
|
+ int len2 = m2.size();
|
|
|
if (len1 < len2)
|
|
|
return -1;
|
|
|
if (len1 > len2)
|
|
@@ -2564,7 +2561,7 @@ class BigInteger{
|
|
|
|
|
|
const int compareMagnitude(std::uint64_t val) {
|
|
|
std::vector<int> m1 = mag;
|
|
|
- int len = m1.length;
|
|
|
+ int len = m1.size();
|
|
|
if (len > 2) {
|
|
|
return 1;
|
|
|
}
|
|
@@ -2859,7 +2856,7 @@ class BigInteger{
|
|
|
|
|
|
int signifFloor = twiceSignifFloor >> 1;
|
|
|
signifFloor &= FloatConsts.SIGNIF_BIT_MASK; // remove the implied bit
|
|
|
- boolean increment = (twiceSignifFloor & 1) != 0
|
|
|
+ bool increment = (twiceSignifFloor & 1) != 0
|
|
|
&& ((signifFloor & 1) != 0 || abs().getLowestSetBit() < shift);
|
|
|
int signifRounded = increment ? signifFloor + 1 : signifFloor;
|
|
|
int bits = ((exponent + FloatConsts.EXP_BIAS))
|
|
@@ -2912,7 +2909,7 @@ class BigInteger{
|
|
|
|
|
|
long signifFloor = twiceSignifFloor >> 1;
|
|
|
signifFloor &= DoubleConsts.SIGNIF_BIT_MASK; // remove the implied bit
|
|
|
- boolean increment = (twiceSignifFloor & 1) != 0
|
|
|
+ bool increment = (twiceSignifFloor & 1) != 0
|
|
|
&& ((signifFloor & 1) != 0 || abs().getLowestSetBit() < shift);
|
|
|
long signifRounded = increment ? signifFloor + 1 : signifFloor;
|
|
|
long bits = (long) ((exponent + DoubleConsts.EXP_BIAS))
|
|
@@ -2930,7 +2927,7 @@ class BigInteger{
|
|
|
// Find first nonzero byte
|
|
|
for (keep = 0; keep < vlen && val[keep] == 0; keep++)
|
|
|
;
|
|
|
- return std::vector<int>(val.egin() + keep,val.begin() + keep + vlen);
|
|
|
+ return std::vector<int>(val.begin() + keep,val.begin() + keep + vlen);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2945,7 +2942,7 @@ class BigInteger{
|
|
|
}
|
|
|
|
|
|
|
|
|
- static std::vector<int> stripLeadingZeroBytes(std::vector<char> a[]) {
|
|
|
+ static std::vector<int> stripLeadingZeroBytes(std::vector<char> a) {
|
|
|
unsigned int byteLength = a.size();
|
|
|
int keep;
|
|
|
|
|
@@ -3001,7 +2998,7 @@ class BigInteger{
|
|
|
}
|
|
|
|
|
|
// Add one to one's complement to generate two's complement
|
|
|
- for (int i=result.length-1; i >= 0; i--) {
|
|
|
+ for (int i=result.size()-1; i >= 0; i--) {
|
|
|
result[i] = (int)((result[i] & LONG_MASK) + 1);
|
|
|
if (result[i] != 0)
|
|
|
break;
|
|
@@ -3022,16 +3019,16 @@ class BigInteger{
|
|
|
* allocate space for one extra output int. */
|
|
|
for (j=keep; j < a.size() && a[j] == 0; j++)
|
|
|
;
|
|
|
- int extraInt = (j == a.length ? 1 : 0);
|
|
|
- std::vector<int> result(a.length - keep + extraInt);
|
|
|
+ int extraInt = (j == a.size() ? 1 : 0);
|
|
|
+ std::vector<int> result(a.size() - keep + extraInt);
|
|
|
|
|
|
/* Copy one's complement of input into output, leaving extra
|
|
|
* int (if it exists) == 0x00 */
|
|
|
- for (int i = keep; i < a.length; i++)
|
|
|
+ for (int i = keep; i < a.size(); i++)
|
|
|
result[i - keep + extraInt] = ~a[i];
|
|
|
|
|
|
// Add one to one's complement to generate two's complement
|
|
|
- for (int i = result.length-1; ++result[i] == 0; i--);
|
|
|
+ for (int i = result.size()-1; ++result[i] == 0; i--);
|
|
|
|
|
|
return result;
|
|
|
}
|
|
@@ -3109,10 +3106,10 @@ class BigInteger{
|
|
|
int getInt(int n) {
|
|
|
if (n < 0)
|
|
|
return 0;
|
|
|
- if (n >= mag.length)
|
|
|
+ if (n >= mag.size())
|
|
|
return signInt();
|
|
|
|
|
|
- int magInt = mag[mag.length - n - 1];
|
|
|
+ int magInt = mag[mag.size() - n - 1];
|
|
|
|
|
|
return (signum >= 0 ? magInt :
|
|
|
(n <= firstNonzeroIntNum() ? -magInt : ~magInt));
|
|
@@ -3126,7 +3123,7 @@ class BigInteger{
|
|
|
|
|
|
// Search for the first nonzero int
|
|
|
int i;
|
|
|
- int mlen = mag.length;
|
|
|
+ int mlen = mag.size();
|
|
|
for (i = mlen - 1; i >= 0 && mag[i] == 0; i--);
|
|
|
fn = mlen - i - 1;
|
|
|
firstNonzeroIntNum = fn + 2; // offset by two to initialize
|
|
@@ -3141,11 +3138,11 @@ class BigInteger{
|
|
|
|
|
|
|
|
|
std::vector<char> magSerializedForm() {
|
|
|
- int len = mag.length;
|
|
|
+ int len = mag.size();
|
|
|
|
|
|
int bitLen = (len == 0 ? 0 : ((len - 1) << 5) + bitLengthForInt(mag[0]));
|
|
|
- int byteLen = (bitLen + 7) >>> 3;
|
|
|
- byte[] result = new byte[byteLen];
|
|
|
+ int byteLen = (bitLen + 7) >> 3;
|
|
|
+ std::vector<char> result(byteLen);
|
|
|
|
|
|
for (int i = byteLen - 1, bytesCopied = 4, intIndex = len - 1, nextInt = 0;
|
|
|
i >= 0; i--) {
|
|
@@ -3153,7 +3150,7 @@ class BigInteger{
|
|
|
nextInt = mag[intIndex--];
|
|
|
bytesCopied = 1;
|
|
|
} else {
|
|
|
- nextInt >>>= 8;
|
|
|
+ nextInt >>= 8;
|
|
|
bytesCopied++;
|
|
|
}
|
|
|
result[i] = (byte)nextInt;
|
|
@@ -3163,7 +3160,7 @@ class BigInteger{
|
|
|
|
|
|
|
|
|
std::int64_t longValueExact() {
|
|
|
- if (mag.length <= 2 && bitLength() <= 63)
|
|
|
+ if (mag.size() <= 2 && bitLength() <= 63)
|
|
|
return longValue();
|
|
|
else
|
|
|
throw std::logic_error("BigInteger out of long range");
|
|
@@ -3171,7 +3168,7 @@ class BigInteger{
|
|
|
|
|
|
|
|
|
int intValueExact() {
|
|
|
- if (mag.length <= 1 && bitLength() <= 31)
|
|
|
+ if (mag.size() <= 1 && bitLength() <= 31)
|
|
|
return intValue();
|
|
|
else
|
|
|
throw std::logic_error("BigInteger out of int range");
|
|
@@ -3179,9 +3176,9 @@ class BigInteger{
|
|
|
|
|
|
|
|
|
short shortValueExact() {
|
|
|
- if (mag.length <= 1 && bitLength() <= 31) {
|
|
|
+ if (mag.size() <= 1 && bitLength() <= 31) {
|
|
|
int value = intValue();
|
|
|
- if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE)
|
|
|
+ if (value >= Short.MIN_VALUE && value <= std::numeric_limits<short>::max())
|
|
|
return shortValue();
|
|
|
}
|
|
|
throw std::logic_error("BigInteger out of short range");
|
|
@@ -3189,9 +3186,9 @@ class BigInteger{
|
|
|
|
|
|
|
|
|
char byteValueExact() {
|
|
|
- if (mag.length <= 1 && bitLength() <= 31) {
|
|
|
+ if (mag.size() <= 1 && bitLength() <= 31) {
|
|
|
int value = intValue();
|
|
|
- if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
|
|
|
+ if (value >= Byte.MIN_VALUE && value <= std::numeric_limits<char>::max())
|
|
|
return byteValue();
|
|
|
}
|
|
|
throw std::logic_error("BigInteger out of byte range");
|