internal static BigInteger consBigInteger(int bitLength, int certainty, Random rnd) { // PRE: bitLength >= 2; // For small numbers get a random prime from the prime table if (bitLength <= 10) { int[] rp = offsetPrimes[bitLength]; return BIprimes[rp[0] + rnd.Next(rp[1])]; } int shiftCount = (-bitLength) & 31; int last = (bitLength + 31) >> 5; BigInteger n = new BigInteger(1, last, new int[last]); last--; do {// To fill the array with random integers for (int i = 0; i < n.numberLength; i++) { n.digits[i] = rnd.Next(); } // To fix to the correct bitLength n.digits[last] = (int)((uint)n.digits[last] | 0x80000000); n.digits[last] = (int)(((uint)n.digits[last]) >> shiftCount); // To create an odd number n.digits[0] |= 1; } while (!isProbablePrime(n, certainty)); return n; }
internal static BigInteger and(BigInteger val, BigInteger that) { if (that.sign == 0 || val.sign == 0) { return BigInteger.ZERO; } if (that.Equals(BigInteger.MINUS_ONE)){ return val; } if (val.Equals(BigInteger.MINUS_ONE)) { return that; } if (val.sign > 0) { if (that.sign > 0) { return andPositive(val, that); } else { return andDiffSigns(val, that); } } else { if (that.sign > 0) { return andDiffSigns(that, val); } else if (val.numberLength > that.numberLength) { return andNegative(val, that); } else { return andNegative(that, val); } } }
internal static BigInteger andDiffSigns(BigInteger positive, BigInteger negative) { int iPos = positive.getFirstNonzeroDigit(); int iNeg = negative.getFirstNonzeroDigit(); // Look if the trailing zeros of the negative will "blank" all // the positive digits if (iNeg >= positive.numberLength) { return BigInteger.ZERO; } int resLength = positive.numberLength; int[] resDigits = new int[resLength]; // Must start from max(iPos, iNeg) int i = Math.Max(iPos, iNeg); if (i == iNeg) { resDigits[i] = -negative.digits[i] & positive.digits[i]; i++; } int limit = Math.Min(negative.numberLength, positive.numberLength); for ( ; i < limit; i++) { resDigits[i] = ~negative.digits[i] & positive.digits[i]; } // if the negative was shorter must copy the remaining digits // from positive if (i >= negative.numberLength) { for ( ; i < positive.numberLength; i++) { resDigits[i] = positive.digits[i]; } } // else positive ended and must "copy" virtual 0's, do nothing then BigInteger result = new BigInteger(1, resLength, resDigits); result.cutOffLeadingZeroes(); return result; }
internal static bool isProbablePrime(BigInteger n, int certainty) { // PRE: n >= 0; if ((certainty <= 0) || ((n.numberLength == 1) && (n.digits[0] == 2))) { return true; } // To discard all even numbers if (!n.testBit(0)) { return false; } // To check if 'n' exists in the table (it fit in 10 bits) if ((n.numberLength == 1) && ((n.digits[0] & 0XFFFFFC00) == 0)) { return (Array.BinarySearch(primes, n.digits[0]) >= 0); } // To check if 'n' is divisible by some prime of the table for (int i = 1; i < primes.Length; i++) { if (Division.remainderArrayByInt(n.digits, n.numberLength, primes[i]) == 0) { return false; } } // To set the number of iterations necessary for Miller-Rabin test int ix; int bitLength = n.bitLength(); for (ix = 2; bitLength < BITS[ix]; ix++) { ; } certainty = Math.Min(ix, 1 + ((certainty - 1) >> 1)); return millerRabin(n, certainty); }
public static BigInteger karatsuba(BigInteger op1, BigInteger op2) { BigInteger temp; if (op2.numberLength > op1.numberLength) { temp = op1; op1 = op2; op2 = temp; } if (op2.numberLength < whenUseKaratsuba) { return multiplyPAP(op1, op2); } /* Karatsuba: u = u1*B + u0 * v = v1*B + v0 * u*v = (u1*v1)*B^2 + ((u1-u0)*(v0-v1) + u1*v1 + u0*v0)*B + u0*v0 */ // ndiv2 = (op1.numberLength / 2) * 32 int ndiv2 = (int)(op1.numberLength & 0xFFFFFFFE) << 4; BigInteger upperOp1 = op1.shiftRight(ndiv2); BigInteger upperOp2 = op2.shiftRight(ndiv2); BigInteger lowerOp1 = op1.subtract(upperOp1.shiftLeft(ndiv2)); BigInteger lowerOp2 = op2.subtract(upperOp2.shiftLeft(ndiv2)); BigInteger upper = karatsuba(upperOp1, upperOp2); BigInteger lower = karatsuba(lowerOp1, lowerOp2); BigInteger middle = karatsuba( upperOp1.subtract(lowerOp1), lowerOp2.subtract(upperOp2)); middle = middle.add(upper).add(lower); middle = middle.shiftLeft(ndiv2); upper = upper.shiftLeft(ndiv2 << 1); return upper.add(middle).add(lower); }
internal static BigInteger add(BigInteger op1, BigInteger op2) { int[] resDigits; int resSign; int op1Sign = op1.sign; int op2Sign = op2.sign; if (op1Sign == 0) { return op2; } if (op2Sign == 0) { return op1; } int op1Len = op1.numberLength; int op2Len = op2.numberLength; if (op1Len + op2Len == 2) { long a = (op1.digits[0] & 0xFFFFFFFFL); long b = (op2.digits[0] & 0xFFFFFFFFL); long ress; int valueLo; int valueHi; if (op1Sign == op2Sign) { ress = a + b; valueLo = (int) ress; valueHi = (int) ((long)(((ulong)ress) >> 32)); return ((valueHi == 0) ? new BigInteger(op1Sign, valueLo) : new BigInteger(op1Sign, 2, new int[] { valueLo, valueHi })); } return BigInteger.valueOf((op1Sign < 0) ? (b - a) : (a - b)); } else if (op1Sign == op2Sign) { resSign = op1Sign; // an augend should not be shorter than addend resDigits = (op1Len >= op2Len) ? add(op1.digits, op1Len, op2.digits, op2Len) : add(op2.digits, op2Len, op1.digits, op1Len); } else { // signs are different int cmp = ((op1Len != op2Len) ? ((op1Len > op2Len) ? 1 : -1) : compareArrays(op1.digits, op2.digits, op1Len)); if (cmp == BigInteger.EQUALS) { return BigInteger.ZERO; } // a minuend should not be shorter than subtrahend if (cmp == BigInteger.GREATER) { resSign = op1Sign; resDigits = subtract(op1.digits, op1Len, op2.digits, op2Len); } else { resSign = op2Sign; resDigits = subtract(op2.digits, op2Len, op1.digits, op1Len); } } BigInteger res = new BigInteger(resSign, resDigits.Length, resDigits); res.cutOffLeadingZeroes(); return res; }
internal static BigInteger andNegative(BigInteger longer, BigInteger shorter) { int iLonger = longer.getFirstNonzeroDigit(); int iShorter = shorter.getFirstNonzeroDigit(); // Does shorter matter? if (iLonger >= shorter.numberLength) { return longer; } int resLength; int[] resDigits; int i = Math.Max(iShorter, iLonger); int digit; if (iShorter > iLonger) { digit = -shorter.digits[i] & ~longer.digits[i]; } else if (iShorter < iLonger) { digit = ~shorter.digits[i] & -longer.digits[i]; } else { digit = -shorter.digits[i] & -longer.digits[i]; } if (digit == 0) { for (i++; i < shorter.numberLength && (digit = ~(longer.digits[i] | shorter.digits[i])) == 0; i++) ; // digit = ~longer.digits[i] & ~shorter.digits[i] if (digit == 0) { // shorter has only the remaining virtual sign bits for ( ; i < longer.numberLength && (digit = ~longer.digits[i]) == 0; i++) ; if (digit == 0) { resLength = longer.numberLength + 1; resDigits = new int[resLength]; resDigits[resLength - 1] = 1; return new BigInteger(-1, resLength, resDigits); } } } resLength = longer.numberLength; resDigits = new int[resLength]; resDigits[i] = -digit; for (i++; i < shorter.numberLength; i++){ // resDigits[i] = ~(~longer.digits[i] & ~shorter.digits[i];) resDigits[i] = longer.digits[i] | shorter.digits[i]; } // shorter has only the remaining virtual sign bits for( ; i < longer.numberLength; i++){ resDigits[i] = longer.digits[i]; } BigInteger result = new BigInteger(-1, resLength, resDigits); return result; }
/** @see BigInteger#doubleValue() */ internal static double bigInteger2Double(BigInteger val) { // val.bitLength() < 64 if ((val.numberLength < 2) || ((val.numberLength == 2) && (val.digits[1] > 0))) { return val.longValue(); } // val.bitLength() >= 33 * 32 > 1024 if (val.numberLength > 32) { return ((val.sign > 0) ? double.PositiveInfinity : double.NegativeInfinity); } return Convert.ToDouble(val.ToString()); }
internal static BigInteger flipBit(BigInteger val, int n) { int resSign = (val.sign == 0) ? 1 : val.sign; int intCount = n >> 5; int bitN = n & 31; int resLength = Math.Max(intCount + 1, val.numberLength) + 1; int[] resDigits = new int[resLength]; int i; int bitNumber = 1 << bitN; Array.Copy(val.digits, 0, resDigits, 0, val.numberLength); if (val.sign < 0) { if (intCount >= val.numberLength) { resDigits[intCount] = bitNumber; } else { //val.sign<0 y intCount < val.numberLength int firstNonZeroDigit = val.getFirstNonzeroDigit(); if (intCount > firstNonZeroDigit) { resDigits[intCount] ^= bitNumber; } else if (intCount < firstNonZeroDigit) { resDigits[intCount] = -bitNumber; for (i=intCount + 1; i < firstNonZeroDigit; i++) { resDigits[i]=-1; } resDigits[i] = resDigits[i]--; } else { i = intCount; resDigits[i] = -((-resDigits[intCount]) ^ bitNumber); if (resDigits[i] == 0) { for (i++; resDigits[i] == -1 ; i++) { resDigits[i] = 0; } resDigits[i]++; } } } } else {//case where val is positive resDigits[intCount] ^= bitNumber; } BigInteger result = new BigInteger(resSign, resLength, resDigits); result.cutOffLeadingZeroes(); return result; }
internal static int bitLength(BigInteger val) { if (val.sign == 0) { return 0; } int bLength = (val.numberLength << 5); int highDigit = val.digits[val.numberLength - 1]; if (val.sign < 0) { int i = val.getFirstNonzeroDigit(); // We reduce the problem to the positive case. if (i == val.numberLength - 1) { highDigit--; } } // Subtracting all sign bits bLength -= BigDecimal.numberOfLeadingZeros(highDigit); return bLength; }
internal static int bitCount(BigInteger val) { int bCount = 0; if (val.sign == 0) { return 0; } int i = val.getFirstNonzeroDigit();; if (val.sign > 0) { for ( ; i < val.numberLength; i++) { bCount += BigDecimal.bitCount(val.digits[i]); } } else {// (sign < 0) // this digit absorbs the carry bCount += BigDecimal.bitCount(-val.digits[i]); for (i++; i < val.numberLength; i++) { bCount += BigDecimal.bitCount(~val.digits[i]); } // We take the complement sum: bCount = (val.numberLength << 5) - bCount; } return bCount; }
internal static BigInteger nextProbablePrime(BigInteger n) { // PRE: n >= 0 int i, j; int certainty; int gapSize = 1024; // for searching of the next probable prime number int[] modules = new int[primes.Length]; bool[] isDivisible = new bool[gapSize]; BigInteger startPoint; BigInteger probPrime; // If n < "last prime of table" searches next prime in the table if ((n.numberLength == 1) && (n.digits[0] >= 0) && (n.digits[0] < primes[primes.Length - 1])) { for (i = 0; n.digits[0] >= primes[i]; i++) { ; } return BIprimes[i]; } /* * Creates a "N" enough big to hold the next probable prime Note that: N < * "next prime" < 2*N */ startPoint = new BigInteger(1, n.numberLength, new int[n.numberLength + 1]); Array.Copy(n.digits, startPoint.digits, n.numberLength); // To fix N to the "next odd number" if (n.testBit(0)) { Elementary.inplaceAdd(startPoint, 2); } else { startPoint.digits[0] |= 1; } // To set the improved certainly of Miller-Rabin j = startPoint.bitLength(); for (certainty = 2; j < BITS[certainty]; certainty++) { ; } // To calculate modules: N mod p1, N mod p2, ... for first primes. for (i = 0; i < primes.Length; i++) { modules[i] = Division.remainder(startPoint, primes[i]) - gapSize; } while (true) { // At this point, all numbers in the gap are initialized as // probably primes Array.Clear(isDivisible, 0, isDivisible.Length); // To discard multiples of first primes for (i = 0; i < primes.Length; i++) { modules[i] = (modules[i] + gapSize) % primes[i]; j = (modules[i] == 0) ? 0 : (primes[i] - modules[i]); for (; j < gapSize; j += primes[i]) { isDivisible[j] = true; } } // To execute Miller-Rabin for non-divisible numbers by all first // primes for (j = 0; j < gapSize; j++) { if (!isDivisible[j]) { probPrime = startPoint.copy(); Elementary.inplaceAdd(probPrime, j); if (millerRabin(probPrime, certainty)) { return probPrime; } } } Elementary.inplaceAdd(startPoint, gapSize); } }
private static void setFromString(BigInteger bi, String val, int radix) { int sign; int[] digits; int numberLength; int stringLength = val.Length; int startChar; int endChar = stringLength; if (val[0] == '-') { sign = -1; startChar = 1; stringLength--; } else { sign = 1; startChar = 0; } /* * We use the following algorithm: split a string into portions of n * characters and convert each portion to an integer according to the * radix. Then convert an exp(radix, n) based number to binary using the * multiplication method. See D. Knuth, The Art of Computer Programming, * vol. 2. */ int charsPerInt = Conversion.digitFitInInt[radix]; int bigRadixDigitsLength = stringLength / charsPerInt; int topChars = stringLength % charsPerInt; if (topChars != 0) { bigRadixDigitsLength++; } digits = new int[bigRadixDigitsLength]; // Get the maximal power of radix that fits in int int bigRadix = Conversion.bigRadices[radix - 2]; // Parse an input string and accumulate the BigInteger's magnitude int digitIndex = 0; // index of digits array int substrEnd = startChar + ((topChars == 0) ? charsPerInt : topChars); int newDigit; for (int substrStart = startChar; substrStart < endChar; substrStart = substrEnd, substrEnd = substrStart + charsPerInt) { int bigRadixDigit = Convert.ToInt32(val.Substring(substrStart, substrEnd - substrStart), radix); newDigit = Multiplication.multiplyByInt(digits, digitIndex, bigRadix); newDigit += Elementary .inplaceAdd(digits, digitIndex, bigRadixDigit); digits[digitIndex++] = newDigit; } numberLength = digitIndex; bi.sign = sign; bi.numberLength = numberLength; bi.digits = digits; bi.cutOffLeadingZeroes(); }
public BigInteger xor(BigInteger val) { return Logical.xor(this, val); }
public BigInteger subtract(BigInteger val) { return Elementary.subtract(this, val); }
public BigInteger remainder(BigInteger divisor) { if (divisor.sign == 0) { throw new ArithmeticException("BigInteger divide by zero"); } int thisLen = numberLength; int divisorLen = divisor.numberLength; if (((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1) : Elementary.compareArrays(digits, divisor.digits, thisLen)) == LESS) { return this; } int resLength = divisorLen; int[] resDigits = new int[resLength]; if (resLength == 1) { resDigits[0] = Division.remainderArrayByInt(digits, thisLen, divisor.digits[0]); } else { int qLen = thisLen - divisorLen + 1; resDigits = Division.divide(null, qLen, digits, thisLen, divisor.digits, divisorLen); } BigInteger result = new BigInteger(sign, resLength, resDigits); result.cutOffLeadingZeroes(); return result; }
public BigInteger multiply(BigInteger val) { // This let us to throw NullReferenceException when val == null if (val.sign == 0) { return ZERO; } if (sign == 0) { return ZERO; } return Multiplication.multiply(this, val); }
public int compareTo(BigInteger val) { if (sign > val.sign) { return GREATER; } if (sign < val.sign) { return LESS; } if (numberLength > val.numberLength) { return sign; } if (numberLength < val.numberLength) { return -val.sign; } // Equal sign and equal numberLength return (sign * Elementary.compareArrays(digits, val.digits, numberLength)); }
public BigInteger modInverse(BigInteger m) { if (m.sign <= 0) { throw new ArithmeticException("BigInteger: modulus not positive"); } // If both are even, no inverse exists if (!(testBit(0) || m.testBit(0))) { throw new ArithmeticException("BigInteger not invertible."); } if (m.isOne()) { return ZERO; } // From now on: (m > 1) BigInteger res = Division.modInverseMontgomery(abs().mod(m), m); if (res.sign == 0) { throw new ArithmeticException("BigInteger not invertible."); } res = ((sign < 0) ? m.subtract(res) : res); return res; }
public BigInteger gcd(BigInteger val) { BigInteger val1 = this.abs(); BigInteger val2 = val.abs(); // To avoid a possible division by zero if (val1.signum() == 0) { return val2; } else if (val2.signum() == 0) { return val1; } // Optimization for small operands // (op2.bitLength() < 64) and (op1.bitLength() < 64) if (((val1.numberLength == 1) || ((val1.numberLength == 2) && (val1.digits[1] > 0))) && (val2.numberLength == 1 || (val2.numberLength == 2 && val2.digits[1] > 0))) { return BigInteger.valueOf(Division.gcdBinary(val1.longValue(), val2 .longValue())); } return Division.gcdBinary(val1.copy(), val2.copy()); }
public BigInteger[] divideAndRemainder(BigInteger divisor) { int divisorSign = divisor.sign; if (divisorSign == 0) { throw new ArithmeticException("BigInteger divide by zero"); } int divisorLen = divisor.numberLength; int[] divisorDigits = divisor.digits; if (divisorLen == 1) { return Division.divideAndRemainderByInteger(this, divisorDigits[0], divisorSign); } // res[0] is a quotient and res[1] is a remainder: int[] thisDigits = digits; int thisLen = numberLength; int cmp = (thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1) : Elementary.compareArrays(thisDigits, divisorDigits, thisLen); if (cmp < 0) { return new BigInteger[] { ZERO, this }; } int thisSign = sign; int quotientLength = thisLen - divisorLen + 1; int remainderLength = divisorLen; int quotientSign = ((thisSign == divisorSign) ? 1 : -1); int[] quotientDigits = new int[quotientLength]; int[] remainderDigits = Division.divide(quotientDigits, quotientLength, thisDigits, thisLen, divisorDigits, divisorLen); BigInteger result0 = new BigInteger(quotientSign, quotientLength, quotientDigits); BigInteger result1 = new BigInteger(thisSign, remainderLength, remainderDigits); result0.cutOffLeadingZeroes(); result1.cutOffLeadingZeroes(); return new BigInteger[] { result0, result1 }; }
public BigInteger divide(BigInteger divisor) { if (divisor.sign == 0) { throw new ArithmeticException("BigInteger divide by zero"); } int divisorSign = divisor.sign; if (divisor.isOne()) { return ((divisor.sign > 0) ? this : this.negate()); } int thisSign = sign; int thisLen = numberLength; int divisorLen = divisor.numberLength; if (thisLen + divisorLen == 2) { long val = (digits[0] & 0xFFFFFFFFL) / (divisor.digits[0] & 0xFFFFFFFFL); if (thisSign != divisorSign) { val = -val; } return valueOf(val); } int cmp = ((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1) : Elementary.compareArrays(digits, divisor.digits, thisLen)); if (cmp == EQUALS) { return ((thisSign == divisorSign) ? ONE : MINUS_ONE); } if (cmp == LESS) { return ZERO; } int resLength = thisLen - divisorLen + 1; int[] resDigits = new int[resLength]; int resSign = ((thisSign == divisorSign) ? 1 : -1); if (divisorLen == 1) { Division.divideArrayByInt(resDigits, digits, thisLen, divisor.digits[0]); } else { Division.divide(resDigits, resLength, digits, thisLen, divisor.digits, divisorLen); } BigInteger result = new BigInteger(resSign, resLength, resDigits); result.cutOffLeadingZeroes(); return result; }
private static bool millerRabin(BigInteger n, int t) { // PRE: n >= 0, t >= 0 BigInteger x; // x := UNIFORM{2...n-1} BigInteger y; // y := x^(q * 2^j) mod n BigInteger n_minus_1 = n.subtract(BigInteger.ONE); // n-1 int bitLength = n_minus_1.bitLength(); // ~ log2(n-1) // (q,k) such that: n-1 = q * 2^k and q is odd int k = n_minus_1.getLowestSetBit(); BigInteger q = n_minus_1.shiftRight(k); Random rnd = new Random(); for (int i = 0; i < t; i++) { // To generate a witness 'x', first it use the primes of table if (i < primes.Length) { x = BIprimes[i]; } else {/* * It generates random witness only if it's necesssary. Note * that all methods would call Miller-Rabin with t <= 50 so * this part is only to do more robust the algorithm */ do { x = new BigInteger(bitLength, rnd); } while ((x.compareTo(n) >= BigInteger.EQUALS) || (x.sign == 0) || x.isOne()); } y = x.modPow(q, n); if (y.isOne() || y.Equals(n_minus_1)) { continue; } for (int j = 1; j < k; j++) { if (y.Equals(n_minus_1)) { continue; } y = y.multiply(y).mod(n); if (y.isOne()) { return false; } } if (!y.Equals(n_minus_1)) { return false; } } return true; }
public BigInteger modPow(BigInteger exponent, BigInteger m) { if (m.sign <= 0) { throw new ArithmeticException("BigInteger: modulus not positive"); } BigInteger _base = this; if (m.isOne() | (exponent.sign > 0 & _base.sign == 0)) { return BigInteger.ZERO; } if (_base.sign == 0 && exponent.sign == 0) { return BigInteger.ONE; } if (exponent.sign < 0) { _base = modInverse(m); exponent = exponent.negate(); } // From now on: (m > 0) and (exponent >= 0) BigInteger res = (m.testBit(0)) ? Division.oddModPow(_base.abs(), exponent, m) : Division.evenModPow(_base.abs(), exponent, m); if ((_base.sign < 0) && exponent.testBit(0)) { // -b^e mod m == ((-1 mod m) * (b^e mod m)) mod m res = m.subtract(BigInteger.ONE).multiply(res).mod(m); } // else exponent is even, so base^exp is positive return res; }
public BigInteger max(BigInteger val) { return ((this.compareTo(val) == GREATER) ? this : val); }
public BigInteger andNot(BigInteger val) { return Logical.andNot(this, val); }
internal static String toDecimalScaledString(BigInteger val, int scale) { int sign = val.sign; int numberLength = val.numberLength; int[] digits = val.digits; int resLengthInChars; int currentChar; char[] result; if (sign == 0) { switch (scale) { case 0: return "0"; //$NON-NLS-1$ case 1: return "0.0"; //$NON-NLS-1$ case 2: return "0.00"; //$NON-NLS-1$ case 3: return "0.000"; //$NON-NLS-1$ case 4: return "0.0000"; //$NON-NLS-1$ case 5: return "0.00000"; //$NON-NLS-1$ case 6: return "0.000000"; //$NON-NLS-1$ default: StringBuilder result1x = new StringBuilder(); if (scale < 0) { result1x.Append("0E+"); //$NON-NLS-1$ } else { result1x.Append("0E"); //$NON-NLS-1$ } result1x.Append(-scale); return result1x.ToString(); } } // one 32-bit unsigned value may contains 10 decimal digits resLengthInChars = numberLength * 10 + 1 + 7; // Explanation why +1+7: // +1 - one char for sign if needed. // +7 - For "special case 2" (see below) we have 7 free chars for // inserting necessary scaled digits. result = new char[resLengthInChars + 1]; // allocated [resLengthInChars+1] characters. // a free latest character may be used for "special case 1" (see // below) currentChar = resLengthInChars; if (numberLength == 1) { int highDigit = digits[0]; if (highDigit < 0) { long v = highDigit & 0xFFFFFFFFL; do { long prev = v; v /= 10; result[--currentChar] = (char) (0x0030 + ((int) (prev - v * 10))); } while (v != 0); } else { int v = highDigit; do { int prev = v; v /= 10; result[--currentChar] = (char) (0x0030 + (prev - v * 10)); } while (v != 0); } } else { int[] temp = new int[numberLength]; int tempLen = numberLength; Array.Copy(digits, temp, tempLen); while (true) { // divide the array of digits by bigRadix and convert // remainders // to characters collecting them in the char array long result11 = 0; for (int i1 = tempLen - 1; i1 >= 0; i1--) { long temp1 = (result11 << 32) + (temp[i1] & 0xFFFFFFFFL); long res = divideLongByBillion(temp1); temp[i1] = (int) res; result11 = (int) (res >> 32); } int resDigit = (int) result11; int previous = currentChar; do { result[--currentChar] = (char) (0x0030 + (resDigit % 10)); } while (((resDigit /= 10) != 0) && (currentChar != 0)); int delta = 9 - previous + currentChar; for (int i = 0; (i < delta) && (currentChar > 0); i++) { result[--currentChar] = '0'; } int j = tempLen - 1; bool bigloop = false; for (; temp[j] == 0; j--) { if (j == 0) { // means temp[0] == 0 bigloop = true; break; } } if(bigloop) break; tempLen = j + 1; } while (result[currentChar] == '0') { currentChar++; } } bool negNumber = (sign < 0); int exponent = resLengthInChars - currentChar - scale - 1; if (scale == 0) { if (negNumber) { result[--currentChar] = '-'; } return new String(result, currentChar, resLengthInChars - currentChar); } if ((scale > 0) && (exponent >= -6)) { if (exponent >= 0) { // special case 1 int insertPoint = currentChar + exponent; for (int j = resLengthInChars - 1; j >= insertPoint; j--) { result[j + 1] = result[j]; } result[++insertPoint] = '.'; if (negNumber) { result[--currentChar] = '-'; } return new String(result, currentChar, resLengthInChars - currentChar + 1); } // special case 2 for (int j = 2; j < -exponent + 1; j++) { result[--currentChar] = '0'; } result[--currentChar] = '.'; result[--currentChar] = '0'; if (negNumber) { result[--currentChar] = '-'; } return new String(result, currentChar, resLengthInChars - currentChar); } int startPoint = currentChar + 1; int endPoint = resLengthInChars; StringBuilder result1 = new StringBuilder(16 + endPoint - startPoint); if (negNumber) { result1.Append('-'); } if (endPoint - startPoint >= 1) { result1.Append(result[currentChar]); result1.Append('.'); result1.Append(result, currentChar + 1, resLengthInChars - currentChar - 1); } else { result1.Append(result, currentChar, resLengthInChars - currentChar); } result1.Append('E'); if (exponent > 0) { result1.Append('+'); } result1.Append(exponent.ToString()); return result1.ToString(); }
public BigInteger min(BigInteger val) { return ((this.compareTo(val) == LESS) ? this : val); }
internal static String bigInteger2String(BigInteger val, int radix) { int sign = val.sign; int numberLength = val.numberLength; int[] digits = val.digits; if (sign == 0) { return "0"; //$NON-NLS-1$ } if (numberLength == 1) { int highDigit = digits[numberLength - 1]; long v = highDigit & 0xFFFFFFFFL; if (sign < 0) { v = -v; } return Convert.ToString(v, radix); } if ((radix == 10) || (radix < 0) || (radix > 26)) { return val.ToString(); } double bitsForRadixDigit; bitsForRadixDigit = Math.Log(radix) / Math.Log(2); int resLengthInChars = (int) (val.abs().bitLength() / bitsForRadixDigit + ((sign < 0) ? 1 : 0)) + 1; char[] result = new char[resLengthInChars]; int currentChar = resLengthInChars; int resDigit; if (radix != 16) { int[] temp = new int[numberLength]; Array.Copy(digits, 0, temp, 0, numberLength); int tempLen = numberLength; int charsPerInt = digitFitInInt[radix]; int i; // get the maximal power of radix that fits in int int bigRadix = bigRadices[radix - 2]; while (true) { // divide the array of digits by bigRadix and convert remainders // to characters collecting them in the char array resDigit = Division.divideArrayByInt(temp, temp, tempLen, bigRadix); int previous = currentChar; do { result[--currentChar] = Convert.ToString(resDigit % radix, radix)[0]; } while (((resDigit /= radix) != 0) && (currentChar != 0)); int delta = charsPerInt - previous + currentChar; for (i = 0; i < delta && currentChar > 0; i++) { result[--currentChar] = '0'; } for (i = tempLen - 1; (i > 0) && (temp[i] == 0); i--) { ; } tempLen = i + 1; if ((tempLen == 1) && (temp[0] == 0)) { // the quotient is 0 break; } } } else { // radix == 16 for (int i = 0; i < numberLength; i++) { for (int j = 0; (j < 8) && (currentChar > 0); j++) { resDigit = digits[i] >> (j << 2) & 0xf; result[--currentChar] = Convert.ToString(resDigit % radix, 16)[0]; } } } while (result[currentChar] == '0') { currentChar++; } if (sign == -1) { result[--currentChar] = '-'; } return new String(result, currentChar, resLengthInChars - currentChar); }
public BigInteger mod(BigInteger m) { if (m.sign <= 0) { throw new ArithmeticException("BigInteger: modulus not positive"); } BigInteger rem = remainder(m); return ((rem.sign < 0) ? rem.add(m) : rem); }