| /* |
| * 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; |
| |
| // BEGIN android-removed |
| // import org.apache.harmony.math.internal.nls.Messages; |
| // END android-removed |
| |
| /** |
| * 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 { |
| |
| // BEGIN android-note |
| // The divide method has been dropped since this functionality |
| // is now available from OpenSSL BIGNUM. |
| // END android-note |
| |
| /** |
| * Divides an array by an integer value. Implements the Knuth's division |
| * algorithm. See D. Knuth, The Art of Computer Programming, vol. 2. |
| * |
| * @param dest the quotient |
| * @param src the dividend |
| * @param srcLength the length of the dividend |
| * @param divisor the divisor |
| * @return remainder |
| */ |
| static int divideArrayByInt(int dest[], int src[], final int srcLength, |
| final int divisor) { |
| |
| long rem = 0; |
| long bLong = divisor & 0xffffffffL; |
| |
| for (int i = srcLength - 1; i >= 0; i--) { |
| long temp = (rem << 32) | (src[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; |
| } |
| } |
| } |
| } |
| dest[i] = (int) (quot & 0xffffffffL); |
| } |
| return (int) rem; |
| } |
| |
| /** |
| * Divides an array by an integer value. Implements the Knuth's division |
| * algorithm. See D. Knuth, The Art of Computer Programming, vol. 2. |
| * |
| * @param src the dividend |
| * @param srcLength the length of the dividend |
| * @param divisor the divisor |
| * @return remainder |
| */ |
| static int remainderArrayByInt(int src[], final int srcLength, |
| final int divisor) { |
| |
| long result = 0; |
| |
| for (int i = srcLength - 1; i >= 0; i--) { |
| long temp = (result << 32) + (src[i] & 0xffffffffL); |
| long res = divideLongByInt(temp, divisor); |
| result = (int) (res >> 32); |
| } |
| return (int) result; |
| } |
| |
| /** |
| * Divides a <code>BigInteger</code> by a signed <code>int</code> and |
| * returns the remainder. |
| * |
| * @param dividend the BigInteger to be divided. Must be non-negative. |
| * @param divisor a signed int |
| * @return divide % divisor |
| */ |
| static int remainder(BigInteger dividend, int divisor) { |
| // BEGIN android-added |
| dividend.establishOldRepresentation("Division.remainder"); |
| // END android-added |
| return remainderArrayByInt(dividend.digits, dividend.numberLength, |
| divisor); |
| } |
| |
| /** |
| * Divides an unsigned long a by an unsigned int b. It is supposed that the |
| * most significant bit of b is set to 1, i.e. b < 0 |
| * |
| * @param a the dividend |
| * @param b the divisor |
| * @return the long value containing the unsigned integer remainder in the |
| * left half and the unsigned integer quotient in the right half |
| */ |
| static long divideLongByInt(long a, int b) { |
| long quot; |
| long rem; |
| long bLong = b & 0xffffffffL; |
| |
| if (a >= 0) { |
| quot = (a / bLong); |
| rem = (a % bLong); |
| } else { |
| /* |
| * Make the dividend positive shifting it right by 1 bit then get |
| * the quotient an remainder and correct them properly |
| */ |
| long aPos = a >>> 1; |
| long bPos = b >>> 1; |
| quot = aPos / bPos; |
| rem = aPos % bPos; |
| // double the remainder and add 1 if a is odd |
| rem = (rem << 1) + (a & 1); |
| if ((b & 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; |
| } |
| } |
| } |
| } |
| return (rem << 32) | (quot & 0xffffffffL); |
| } |
| |
| /** |
| * Computes the quotient and the remainder after a division by an {@code int} |
| * number. |
| * |
| * @return an array of the form {@code [quotient, remainder]}. |
| */ |
| static BigInteger[] divideAndRemainderByInteger(BigInteger val, |
| int divisor, int divisorSign) { |
| // BEGIN android-added |
| val.establishOldRepresentation("Division.divideAndRemainderByInteger"); |
| // END android-added |
| // res[0] is a quotient and res[1] is a remainder: |
| int[] valDigits = val.digits; |
| int valLen = val.numberLength; |
| int valSign = val.sign; |
| if (valLen == 1) { |
| long a = (valDigits[0] & 0xffffffffL); |
| long b = (divisor & 0xffffffffL); |
| long quo = a / b; |
| long rem = a % b; |
| if (valSign != divisorSign) { |
| quo = -quo; |
| } |
| if (valSign < 0) { |
| rem = -rem; |
| } |
| return new BigInteger[] { BigInteger.valueOf(quo), |
| BigInteger.valueOf(rem) }; |
| } |
| int quotientLength = valLen; |
| int quotientSign = ((valSign == divisorSign) ? 1 : -1); |
| int quotientDigits[] = new int[quotientLength]; |
| int remainderDigits[]; |
| remainderDigits = new int[] { Division.divideArrayByInt( |
| quotientDigits, valDigits, valLen, divisor) }; |
| BigInteger result0 = new BigInteger(quotientSign, quotientLength, |
| quotientDigits); |
| BigInteger result1 = new BigInteger(valSign, 1, remainderDigits); |
| result0.cutOffLeadingZeroes(); |
| result1.cutOffLeadingZeroes(); |
| return new BigInteger[] { result0, result1 }; |
| } |
| |
| // BEGIN android-note |
| // A big part of this class that only has been used by the divide method |
| // has been dropped in favor of using the BIGNUM impl. |
| // END android-note |
| } |