Home | History | Annotate | Download | only in math
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package java.math;
     19 
     20 // BEGIN android-removed
     21 // import org.apache.harmony.math.internal.nls.Messages;
     22 // END android-removed
     23 
     24 /**
     25  * Static library that provides all operations related with division and modular
     26  * arithmetic to {@link BigInteger}. Some methods are provided in both mutable
     27  * and immutable way. There are several variants provided listed below:
     28  *
     29  * <ul type="circle">
     30  * <li> <b>Division</b>
     31  * <ul type="circle">
     32  * <li>{@link BigInteger} division and remainder by {@link BigInteger}.</li>
     33  * <li>{@link BigInteger} division and remainder by {@code int}.</li>
     34  * <li><i>gcd</i> between {@link BigInteger} numbers.</li>
     35  * </ul>
     36  * </li>
     37  * <li> <b>Modular arithmetic </b>
     38  * <ul type="circle">
     39  * <li>Modular exponentiation between {@link BigInteger} numbers.</li>
     40  * <li>Modular inverse of a {@link BigInteger} numbers.</li>
     41  * </ul>
     42  * </li>
     43  *</ul>
     44  */
     45 class Division {
     46 
     47     // BEGIN android-note
     48     // The divide method has been dropped since this functionality
     49     // is now available from OpenSSL BIGNUM.
     50     // END android-note
     51 
     52     /**
     53      * Divides an array by an integer value. Implements the Knuth's division
     54      * algorithm. See D. Knuth, The Art of Computer Programming, vol. 2.
     55      *
     56      * @param dest the quotient
     57      * @param src the dividend
     58      * @param srcLength the length of the dividend
     59      * @param divisor the divisor
     60      * @return remainder
     61      */
     62     static int divideArrayByInt(int dest[], int src[], final int srcLength,
     63             final int divisor) {
     64 
     65         long rem = 0;
     66         long bLong = divisor & 0xffffffffL;
     67 
     68         for (int i = srcLength - 1; i >= 0; i--) {
     69             long temp = (rem << 32) | (src[i] & 0xffffffffL);
     70             long quot;
     71             if (temp >= 0) {
     72                 quot = (temp / bLong);
     73                 rem = (temp % bLong);
     74             } else {
     75                 /*
     76                  * make the dividend positive shifting it right by 1 bit then
     77                  * get the quotient an remainder and correct them properly
     78                  */
     79                 long aPos = temp >>> 1;
     80                 long bPos = divisor >>> 1;
     81                 quot = aPos / bPos;
     82                 rem = aPos % bPos;
     83                 // double the remainder and add 1 if a is odd
     84                 rem = (rem << 1) + (temp & 1);
     85                 if ((divisor & 1) != 0) {
     86                     // the divisor is odd
     87                     if (quot <= rem) {
     88                         rem -= quot;
     89                     } else {
     90                         if (quot - rem <= bLong) {
     91                             rem += bLong - quot;
     92                             quot -= 1;
     93                         } else {
     94                             rem += (bLong << 1) - quot;
     95                             quot -= 2;
     96                         }
     97                     }
     98                 }
     99             }
    100             dest[i] = (int) (quot & 0xffffffffL);
    101         }
    102         return (int) rem;
    103     }
    104 
    105     /**
    106      * Divides an array by an integer value. Implements the Knuth's division
    107      * algorithm. See D. Knuth, The Art of Computer Programming, vol. 2.
    108      *
    109      * @param src the dividend
    110      * @param srcLength the length of the dividend
    111      * @param divisor the divisor
    112      * @return remainder
    113      */
    114     static int remainderArrayByInt(int src[], final int srcLength,
    115             final int divisor) {
    116 
    117         long result = 0;
    118 
    119         for (int i = srcLength - 1; i >= 0; i--) {
    120             long temp = (result << 32) + (src[i] & 0xffffffffL);
    121             long res = divideLongByInt(temp, divisor);
    122             result = (int) (res >> 32);
    123         }
    124         return (int) result;
    125     }
    126 
    127     /**
    128      * Divides a <code>BigInteger</code> by a signed <code>int</code> and
    129      * returns the remainder.
    130      *
    131      * @param dividend the BigInteger to be divided. Must be non-negative.
    132      * @param divisor a signed int
    133      * @return divide % divisor
    134      */
    135     static int remainder(BigInteger dividend, int divisor) {
    136         // BEGIN android-added
    137         dividend.establishOldRepresentation("Division.remainder");
    138         // END android-added
    139         return remainderArrayByInt(dividend.digits, dividend.numberLength,
    140                 divisor);
    141     }
    142 
    143     /**
    144      * Divides an unsigned long a by an unsigned int b. It is supposed that the
    145      * most significant bit of b is set to 1, i.e. b < 0
    146      *
    147      * @param a the dividend
    148      * @param b the divisor
    149      * @return the long value containing the unsigned integer remainder in the
    150      *         left half and the unsigned integer quotient in the right half
    151      */
    152     static long divideLongByInt(long a, int b) {
    153         long quot;
    154         long rem;
    155         long bLong = b & 0xffffffffL;
    156 
    157         if (a >= 0) {
    158             quot = (a / bLong);
    159             rem = (a % bLong);
    160         } else {
    161             /*
    162              * Make the dividend positive shifting it right by 1 bit then get
    163              * the quotient an remainder and correct them properly
    164              */
    165             long aPos = a >>> 1;
    166             long bPos = b >>> 1;
    167             quot = aPos / bPos;
    168             rem = aPos % bPos;
    169             // double the remainder and add 1 if a is odd
    170             rem = (rem << 1) + (a & 1);
    171             if ((b & 1) != 0) { // the divisor is odd
    172                 if (quot <= rem) {
    173                     rem -= quot;
    174                 } else {
    175                     if (quot - rem <= bLong) {
    176                         rem += bLong - quot;
    177                         quot -= 1;
    178                     } else {
    179                         rem += (bLong << 1) - quot;
    180                         quot -= 2;
    181                     }
    182                 }
    183             }
    184         }
    185         return (rem << 32) | (quot & 0xffffffffL);
    186     }
    187 
    188     /**
    189      * Computes the quotient and the remainder after a division by an {@code int}
    190      * number.
    191      *
    192      * @return an array of the form {@code [quotient, remainder]}.
    193      */
    194     static BigInteger[] divideAndRemainderByInteger(BigInteger val,
    195             int divisor, int divisorSign) {
    196         // BEGIN android-added
    197         val.establishOldRepresentation("Division.divideAndRemainderByInteger");
    198         // END android-added
    199         // res[0] is a quotient and res[1] is a remainder:
    200         int[] valDigits = val.digits;
    201         int valLen = val.numberLength;
    202         int valSign = val.sign;
    203         if (valLen == 1) {
    204             long a = (valDigits[0] & 0xffffffffL);
    205             long b = (divisor & 0xffffffffL);
    206             long quo = a / b;
    207             long rem = a % b;
    208             if (valSign != divisorSign) {
    209                 quo = -quo;
    210             }
    211             if (valSign < 0) {
    212                 rem = -rem;
    213             }
    214             return new BigInteger[] { BigInteger.valueOf(quo),
    215                     BigInteger.valueOf(rem) };
    216         }
    217         int quotientLength = valLen;
    218         int quotientSign = ((valSign == divisorSign) ? 1 : -1);
    219         int quotientDigits[] = new int[quotientLength];
    220         int remainderDigits[];
    221         remainderDigits = new int[] { Division.divideArrayByInt(
    222                 quotientDigits, valDigits, valLen, divisor) };
    223         BigInteger result0 = new BigInteger(quotientSign, quotientLength,
    224                 quotientDigits);
    225         BigInteger result1 = new BigInteger(valSign, 1, remainderDigits);
    226         result0.cutOffLeadingZeroes();
    227         result1.cutOffLeadingZeroes();
    228         return new BigInteger[] { result0, result1 };
    229     }
    230 
    231     // BEGIN android-note
    232     // A big part of this class that only has been used by the divide method
    233     // has been dropped in favor of using the BIGNUM impl.
    234     // END android-note
    235 }
    236