/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package java.math; /** * Static library that provides all operations related with division and modular * arithmetic to {@link BigInteger}. Some methods are provided in both mutable * and immutable way. There are several variants provided listed below: * * <ul type="circle"> * <li> <b>Division</b> * <ul type="circle"> * <li>{@link BigInteger} division and remainder by {@link BigInteger}.</li> * <li>{@link BigInteger} division and remainder by {@code int}.</li> * <li><i>gcd</i> between {@link BigInteger} numbers.</li> * </ul> * </li> * <li> <b>Modular arithmetic </b> * <ul type="circle"> * <li>Modular exponentiation between {@link BigInteger} numbers.</li> * <li>Modular inverse of a {@link BigInteger} numbers.</li> * </ul> * </li> *</ul> */ class Division { /** * Divides an array by an integer value. Implements the Knuth's division * algorithm. See D. Knuth, The Art of Computer Programming, vol. 2. * * @return remainder */ static int divideArrayByInt(int[] quotient, int[] dividend, final int dividendLength, final int divisor) { long rem = 0; long bLong = divisor & 0xffffffffL; for (int i = dividendLength - 1; i >= 0; i--) { long temp = (rem << 32) | (dividend[i] & 0xffffffffL); long quot; if (temp >= 0) { quot = (temp / bLong); rem = (temp % bLong); } else { /* * make the dividend positive shifting it right by 1 bit then * get the quotient an remainder and correct them properly */ long aPos = temp >>> 1; long bPos = divisor >>> 1; quot = aPos / bPos; rem = aPos % bPos; // double the remainder and add 1 if a is odd rem = (rem << 1) + (temp & 1); if ((divisor & 1) != 0) { // the divisor is odd if (quot <= rem) { rem -= quot; } else { if (quot - rem <= bLong) { rem += bLong - quot; quot -= 1; } else { rem += (bLong << 1) - quot; quot -= 2; } } } } quotient[i] = (int) (quot & 0xffffffffL); } return (int) rem; } }