private static BigDecimal divideAndRound(BigInteger bdividend, BigInteger bdivisor, int scale, int roundingMode, int preferredScale) { boolean isRemainderZero; // record remainder is zero or not int qsign; // quotient sign // Descend into mutables for faster remainder checks MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag); MutableBigInteger mq = new MutableBigInteger(); MutableBigInteger mdivisor = new MutableBigInteger(bdivisor.mag); MutableBigInteger mr = mdividend.divide(mdivisor, mq); ...
if (p.isOdd()) return modInverse(p); if (isEven()) throw new ArithmeticException("BigInteger not invertible."); int powersOf2 = p.getLowestSetBit(); MutableBigInteger oddMod = new MutableBigInteger(p); oddMod.rightShift(powersOf2); if (oddMod.isOne()) return modInverseMP2(powersOf2); MutableBigInteger oddPart = modInverse(oddMod); MutableBigInteger evenPart = modInverseMP2(powersOf2); MutableBigInteger y1 = modInverseBP2(oddMod, powersOf2); MutableBigInteger y2 = oddMod.modInverseMP2(powersOf2); MutableBigInteger temp1 = new MutableBigInteger(); MutableBigInteger temp2 = new MutableBigInteger(); MutableBigInteger result = new MutableBigInteger(); oddPart.leftShift(powersOf2); oddPart.multiply(y1, result); evenPart.multiply(oddMod, temp1);
MutableBigInteger p = new MutableBigInteger(mod); MutableBigInteger f = new MutableBigInteger(this); MutableBigInteger g = new MutableBigInteger(p); SignedMutableBigInteger c = new SignedMutableBigInteger(1); SignedMutableBigInteger d = new SignedMutableBigInteger(); if (f.isEven()) { int trailingZeros = f.getLowestSetBit(); f.rightShift(trailingZeros); d.leftShift(trailingZeros); k = trailingZeros; while(!f.isOne()) { if (f.isZero()) throw new ArithmeticException("BigInteger not invertible."); if (f.compare(g) < 0) { temp = f; f = g; g = temp; sTemp = d; d = c; c = sTemp; f.subtract(g); c.signedSubtract(d); } else { // If f != g (mod 4) f.add(g); c.signedAdd(d); int trailingZeros = f.getLowestSetBit(); f.rightShift(trailingZeros);
MutableBigInteger b = new MutableBigInteger(1); b.leftShift(k); MutableBigInteger mod = new MutableBigInteger(b); MutableBigInteger a = new MutableBigInteger(this); MutableBigInteger q = new MutableBigInteger(); MutableBigInteger r = b.divide(a, q); MutableBigInteger t1 = new MutableBigInteger(q); MutableBigInteger t0 = new MutableBigInteger(1); MutableBigInteger temp = new MutableBigInteger(); while (!b.isOne()) { r = a.divide(b, q); t1.mul(q.value[q.offset], temp); else q.multiply(t1, temp); swapper = q; q = temp; temp = swapper; t0.add(q); if (a.isOne()) return t0; r = b.divide(a, q); t0.mul(q.value[q.offset], temp);
MutableBigInteger rem = new MutableBigInteger(new int[intLen + 1]); System.arraycopy(value, offset, rem.value, 1, intLen); rem.intLen = intLen; rem.leftShift(shift); qrem = (int) (nChunk - (qhat * dhLong)); } else { divWord(qWord, nChunk, dh); qhat = qWord[0]; qrem = qWord[1]; if (unsignedLongCompare(estProduct, rs)) { qhat--; qrem = (int)((qrem & LONG_MASK) + dhLong); estProduct -= (dl & LONG_MASK); rs = ((qrem & LONG_MASK) << 32) | nl; if (unsignedLongCompare(estProduct, rs)) qhat--; int borrow = mulsub(rem.value, divisor, qhat, dlen, j+rem.offset); divadd(divisor, rem.value, j+1+rem.offset); qhat--; rem.rightShift(shift); quotient.normalize();
/** * Returns a BigInteger whose value is {@code (this / val)}. * * @param val value by which this BigInteger is to be divided. * @return {@code this / val} * @throws ArithmeticException if {@code val} is zero. */ public BigInteger divide(BigInteger val) { MutableBigInteger q = new MutableBigInteger(), a = new MutableBigInteger(this.mag), b = new MutableBigInteger(val.mag); a.divide(b, q); return q.toBigInteger(this.signum == val.signum ? 1 : -1); }
bdividend = BigInteger.valueOf(ldividend); MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag); mq = new MutableBigInteger(); if (ldivisor != INFLATED) { r = mdividend.divide(ldivisor, mq); isRemainderZero = (r == 0); qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum; } else { mdivisor = new MutableBigInteger(bdivisor.mag); mr = mdividend.divide(mdivisor, mq); isRemainderZero = mr.isZero(); qsign = (bdividend.signum != bdivisor.signum) ? -1 : 1; cmpFracHalf = mr.compareHalf(mdivisor); increment = false; else // roundingMode == ROUND_HALF_EVEN, true iff quotient is odd increment = isLongDivision ? (q & 1L) != 0L : mq.isOdd(); else { if (increment) mq.add(MutableBigInteger.ONE); res = mq.toBigDecimal(qsign, scale);
static MutableBigInteger fixup(MutableBigInteger c, MutableBigInteger p, int k) { MutableBigInteger temp = new MutableBigInteger(); // Set r to the multiplicative inverse of p mod 2^32 int r = -inverseMod32(p.value[p.offset+p.intLen-1]); for(int i=0, numWords = k >> 5; i<numWords; i++) { // V = R * c (mod 2^j) int v = r * c.value[c.offset + c.intLen-1]; // c = c + (v * p) p.mul(v, temp); c.add(temp); // c = c / 2^j c.intLen--; } int numBits = k & 0x1f; if (numBits != 0) { // V = R * c (mod 2^j) int v = r * c.value[c.offset + c.intLen-1]; v &= ((1<<numBits) - 1); // c = c + (v * p) p.mul(v, temp); c.add(temp); // c = c / 2^j c.rightShift(numBits); } // In theory, c may be greater than p at this point (Very rare!) while (c.compare(p) >= 0) c.subtract(p); return c; }
MutableBigInteger r = new MutableBigInteger(); int s1 = u.getLowestSetBit(); int s2 = v.getLowestSetBit(); int k = (s1 < s2) ? s1 : s2; if (k != 0) { u.rightShift(k); v.rightShift(k); while ((lb = t.getLowestSetBit()) >= 0) { t.rightShift(lb); int x = u.value[u.offset]; int y = v.value[v.offset]; x = binaryGcd(x, y); r.value[0] = x; r.intLen = 1; r.offset = 0; if (k > 0) r.leftShift(k); return r; if ((tsign = u.difference(v)) == 0) break; t = (tsign >= 0) ? u : v; u.leftShift(k); return u;
MutableBigInteger modInverseMP2(int k) { if (isEven()) throw new ArithmeticException("Non-invertible. (GCD != 1)"); if (k > 64) return euclidModInverse(k); int t = inverseMod32(value[offset+intLen-1]); if (k < 33) { t = (k == 32 ? t : t & ((1 << k) - 1)); return new MutableBigInteger(t); } long pLong = (value[offset+intLen-1] & LONG_MASK); if (intLen > 1) pLong |= ((long)value[offset+intLen-2] << 32); long tLong = t & LONG_MASK; tLong = tLong * (2 - pLong * tLong); // 1 more Newton iter step tLong = (k == 64 ? tLong : tLong & ((1L << k) - 1)); MutableBigInteger result = new MutableBigInteger(new int[2]); result.value[0] = (int)(tLong >>> 32); result.value[1] = (int)tLong; result.intLen = 2; result.normalize(); return result; }
return new MutableBigInteger(); int cmp = compare(b); return new MutableBigInteger(this); quotient.value[0] = quotient.intLen = 1; quotient.offset = 0; return new MutableBigInteger(); quotient.clear(); int r = divideOneWord(b.value[b.offset], quotient); if (r == 0) return new MutableBigInteger(); return new MutableBigInteger(r); return divideMagnitude(div, quotient);
int inv = -MutableBigInteger.inverseMod32(mod[modLen-1]); MutableBigInteger q = new MutableBigInteger(), a2 = new MutableBigInteger(a), b2 = new MutableBigInteger(mod); MutableBigInteger r= a2.divide(b2, q); table[0] = r.toIntArray();
/** * Calculate GCD of this and b. This and b are changed by the computation. */ MutableBigInteger hybridGCD(MutableBigInteger b) { // Use Euclid's algorithm until the numbers are approximately the // same length, then use the binary GCD algorithm to find the GCD. MutableBigInteger a = this; MutableBigInteger q = new MutableBigInteger(); while (b.intLen != 0) { if (Math.abs(a.intLen - b.intLen) < 2) return a.binaryGCD(b); MutableBigInteger r = a.divide(b, q); a = b; b = r; } return a; }
/** * Internally used to calculate the quotient of this div v and places the * quotient in the provided MutableBigInteger object and the remainder is * returned. * * @return the remainder of the division will be returned. */ long divide(long v, MutableBigInteger quotient) { if (v == 0) throw new ArithmeticException("BigInteger divide by zero"); // Dividend is zero if (intLen == 0) { quotient.intLen = quotient.offset = 0; return 0; } if (v < 0) v = -v; int d = (int)(v >>> 32); quotient.clear(); // Special case on word divisor if (d == 0) return divideOneWord((int)v, quotient) & LONG_MASK; else { int[] div = new int[]{ d, (int)(v & LONG_MASK) }; return divideMagnitude(div, quotient).toLong(); } }
/** * Returns a BigInteger whose value is the greatest common divisor of * {@code abs(this)} and {@code abs(val)}. Returns 0 if * {@code this==0 && val==0}. * * @param val value with which the GCD is to be computed. * @return {@code GCD(abs(this), abs(val))} */ public BigInteger gcd(BigInteger val) { if (val.signum == 0) return this.abs(); else if (this.signum == 0) return val.abs(); MutableBigInteger a = new MutableBigInteger(this); MutableBigInteger b = new MutableBigInteger(val); MutableBigInteger result = a.hybridGCD(b); return result.toBigInteger(1); }
/** * Returns a BigInteger whose value is {@code (this}<sup>-1</sup> {@code mod m)}. * * @param m the modulus. * @return {@code this}<sup>-1</sup> {@code mod m}. * @throws ArithmeticException {@code m} ≤ 0, or this BigInteger * has no multiplicative inverse mod m (that is, this BigInteger * is not <i>relatively prime</i> to m). */ public BigInteger modInverse(BigInteger m) { if (m.signum != 1) throw new ArithmeticException("BigInteger: modulus not positive"); if (m.equals(ONE)) return ZERO; // Calculate (this mod m) BigInteger modVal = this; if (signum < 0 || (this.compareMagnitude(m) >= 0)) modVal = this.mod(m); if (modVal.equals(ONE)) return ONE; MutableBigInteger a = new MutableBigInteger(modVal); MutableBigInteger b = new MutableBigInteger(m); MutableBigInteger result = a.mutableModInverse(b); return result.toBigInteger(1); }
result = a1.multiply(m2).multiply(y1).add(a2.multiply(m1).multiply(y2)).mod(m); } else { MutableBigInteger t1 = new MutableBigInteger(); new MutableBigInteger(a1.multiply(m2)).multiply(new MutableBigInteger(y1), t1); MutableBigInteger t2 = new MutableBigInteger(); new MutableBigInteger(a2.multiply(m1)).multiply(new MutableBigInteger(y2), t2); t1.add(t2); MutableBigInteger q = new MutableBigInteger(); result = t1.divide(new MutableBigInteger(m), q).toBigInteger();
static MutableBigInteger modInverseBP2(MutableBigInteger mod, int k) { // Copy the mod to protect original return fixup(new MutableBigInteger(1), new MutableBigInteger(mod), k); }
MutableBigInteger b = new MutableBigInteger(base); MutableBigInteger q = new MutableBigInteger(); do { start = b.divideOneWord(convertedStep, q);