jdk/src/java.base/share/classes/java/math/BigInteger.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 8069539 Sdiff jdk/src/java.base/share/classes/java/math

jdk/src/java.base/share/classes/java/math/BigInteger.java

Print this page




1946         }
1947         int len = mag.length;
1948 
1949         if (len < KARATSUBA_SQUARE_THRESHOLD) {
1950             int[] z = squareToLen(mag, len, null);
1951             return new BigInteger(trustedStripLeadingZeroInts(z), 1);
1952         } else {
1953             if (len < TOOM_COOK_SQUARE_THRESHOLD) {
1954                 return squareKaratsuba();
1955             } else {
1956                 return squareToomCook3();
1957             }
1958         }
1959     }
1960 
1961     /**
1962      * Squares the contents of the int array x. The result is placed into the
1963      * int array z.  The contents of x are not changed.
1964      */
1965     private static final int[] squareToLen(int[] x, int len, int[] z) {





































1966         /*
1967          * The algorithm used here is adapted from Colin Plumb's C library.
1968          * Technique: Consider the partial products in the multiplication
1969          * of "abcde" by itself:
1970          *
1971          *               a  b  c  d  e
1972          *            *  a  b  c  d  e
1973          *          ==================
1974          *              ae be ce de ee
1975          *           ad bd cd dd de
1976          *        ac bc cc cd ce
1977          *     ab bb bc bd be
1978          *  aa ab ac ad ae
1979          *
1980          * Note that everything above the main diagonal:
1981          *              ae be ce de = (abcd) * e
1982          *           ad bd cd       = (abc) * d
1983          *        ac bc             = (ab) * c
1984          *     ab                   = (a) * b
1985          *
1986          * is a copy of everything below the main diagonal:
1987          *                       de
1988          *                 cd ce
1989          *           bc bd be
1990          *     ab ac ad ae
1991          *
1992          * Thus, the sum is 2 * (off the diagonal) + diagonal.
1993          *
1994          * This is accumulated beginning with the diagonal (which
1995          * consist of the squares of the digits of the input), which is then
1996          * divided by two, the off-diagonal added, and multiplied by two
1997          * again.  The low bit is simply a copy of the low bit of the
1998          * input, so it doesn't need special care.
1999          */
2000         int zlen = len << 1;
2001         if (z == null || z.length < zlen)
2002             z = new int[zlen];
2003 
2004         // Store the squares, right shifted one bit (i.e., divided by 2)
2005         int lastProductLowWord = 0;
2006         for (int j=0, i=0; j < len; j++) {
2007             long piece = (x[j] & LONG_MASK);
2008             long product = piece * piece;
2009             z[i++] = (lastProductLowWord << 31) | (int)(product >>> 33);
2010             z[i++] = (int)(product >>> 1);
2011             lastProductLowWord = (int)product;
2012         }
2013 
2014         // Add in off-diagonal sums
2015         for (int i=len, offset=1; i > 0; i--, offset+=2) {
2016             int t = x[i-1];
2017             t = mulAdd(z, x, offset, i-1, t);
2018             addOne(z, offset-1, i, t);
2019         }
2020 
2021         // Shift back up and set low bit
2022         primitiveLeftShift(z, zlen, 1);


2840 
2841     /**
2842      * Subtracts two numbers of same length, returning borrow.
2843      */
2844     private static int subN(int[] a, int[] b, int len) {
2845         long sum = 0;
2846 
2847         while (--len >= 0) {
2848             sum = (a[len] & LONG_MASK) -
2849                  (b[len] & LONG_MASK) + (sum >> 32);
2850             a[len] = (int)sum;
2851         }
2852 
2853         return (int)(sum >> 32);
2854     }
2855 
2856     /**
2857      * Multiply an array by one word k and add to result, return the carry
2858      */
2859     static int mulAdd(int[] out, int[] in, int offset, int len, int k) {


























2860         long kLong = k & LONG_MASK;
2861         long carry = 0;
2862 
2863         offset = out.length-offset - 1;
2864         for (int j=len-1; j >= 0; j--) {
2865             long product = (in[j] & LONG_MASK) * kLong +
2866                            (out[offset] & LONG_MASK) + carry;
2867             out[offset--] = (int)product;
2868             carry = product >>> 32;
2869         }
2870         return (int)carry;
2871     }
2872 
2873     /**
2874      * Add one word to the number a mlen words into a. Return the resulting
2875      * carry.
2876      */
2877     static int addOne(int[] a, int offset, int mlen, int carry) {
2878         offset = a.length-1-mlen-offset;
2879         long t = (a[offset] & LONG_MASK) + (carry & LONG_MASK);




1946         }
1947         int len = mag.length;
1948 
1949         if (len < KARATSUBA_SQUARE_THRESHOLD) {
1950             int[] z = squareToLen(mag, len, null);
1951             return new BigInteger(trustedStripLeadingZeroInts(z), 1);
1952         } else {
1953             if (len < TOOM_COOK_SQUARE_THRESHOLD) {
1954                 return squareKaratsuba();
1955             } else {
1956                 return squareToomCook3();
1957             }
1958         }
1959     }
1960 
1961     /**
1962      * Squares the contents of the int array x. The result is placed into the
1963      * int array z.  The contents of x are not changed.
1964      */
1965     private static final int[] squareToLen(int[] x, int len, int[] z) {
1966          int zlen = len << 1;
1967          if (z == null || z.length < zlen)
1968              z = new int[zlen];
1969  
1970          // Execute checks before calling intrinsified method.
1971          implSquareToLenChecks(x, len, z, zlen);
1972          return implSquareToLen(x, len, z, zlen);
1973      }
1974  
1975      /**
1976       * Parameters validation.
1977       */
1978      private static void implSquareToLenChecks(int[] x, int len, int[] z, int zlen) throws RuntimeException {
1979          if (len < 1) {
1980              throw new IllegalArgumentException("invalid input length: " + len);
1981          }
1982          if (len > x.length) {
1983              throw new IllegalArgumentException("input length out of bound: " +
1984                                         len + " > " + x.length);
1985          }
1986          if (len * 2 > z.length) {
1987              throw new IllegalArgumentException("input length out of bound: " +
1988                                         (len * 2) + " > " + z.length);
1989          }
1990          if (zlen < 1) {
1991              throw new IllegalArgumentException("invalid input length: " + zlen);
1992          }
1993          if (zlen > z.length) {
1994              throw new IllegalArgumentException("input length out of bound: " +
1995                                         len + " > " + z.length);
1996          }
1997      }
1998  
1999      /**
2000       * Java Runtime may use intrinsic for this method.
2001       */
2002      private static final int[] implSquareToLen(int[] x, int len, int[] z, int zlen) {
2003         /*
2004          * The algorithm used here is adapted from Colin Plumb's C library.
2005          * Technique: Consider the partial products in the multiplication
2006          * of "abcde" by itself:
2007          *
2008          *               a  b  c  d  e
2009          *            *  a  b  c  d  e
2010          *          ==================
2011          *              ae be ce de ee
2012          *           ad bd cd dd de
2013          *        ac bc cc cd ce
2014          *     ab bb bc bd be
2015          *  aa ab ac ad ae
2016          *
2017          * Note that everything above the main diagonal:
2018          *              ae be ce de = (abcd) * e
2019          *           ad bd cd       = (abc) * d
2020          *        ac bc             = (ab) * c
2021          *     ab                   = (a) * b
2022          *
2023          * is a copy of everything below the main diagonal:
2024          *                       de
2025          *                 cd ce
2026          *           bc bd be
2027          *     ab ac ad ae
2028          *
2029          * Thus, the sum is 2 * (off the diagonal) + diagonal.
2030          *
2031          * This is accumulated beginning with the diagonal (which
2032          * consist of the squares of the digits of the input), which is then
2033          * divided by two, the off-diagonal added, and multiplied by two
2034          * again.  The low bit is simply a copy of the low bit of the
2035          * input, so it doesn't need special care.
2036          */



2037 
2038         // Store the squares, right shifted one bit (i.e., divided by 2)
2039         int lastProductLowWord = 0;
2040         for (int j=0, i=0; j < len; j++) {
2041             long piece = (x[j] & LONG_MASK);
2042             long product = piece * piece;
2043             z[i++] = (lastProductLowWord << 31) | (int)(product >>> 33);
2044             z[i++] = (int)(product >>> 1);
2045             lastProductLowWord = (int)product;
2046         }
2047 
2048         // Add in off-diagonal sums
2049         for (int i=len, offset=1; i > 0; i--, offset+=2) {
2050             int t = x[i-1];
2051             t = mulAdd(z, x, offset, i-1, t);
2052             addOne(z, offset-1, i, t);
2053         }
2054 
2055         // Shift back up and set low bit
2056         primitiveLeftShift(z, zlen, 1);


2874 
2875     /**
2876      * Subtracts two numbers of same length, returning borrow.
2877      */
2878     private static int subN(int[] a, int[] b, int len) {
2879         long sum = 0;
2880 
2881         while (--len >= 0) {
2882             sum = (a[len] & LONG_MASK) -
2883                  (b[len] & LONG_MASK) + (sum >> 32);
2884             a[len] = (int)sum;
2885         }
2886 
2887         return (int)(sum >> 32);
2888     }
2889 
2890     /**
2891      * Multiply an array by one word k and add to result, return the carry
2892      */
2893     static int mulAdd(int[] out, int[] in, int offset, int len, int k) {
2894         implMulAddCheck(out, in, offset, len, k);
2895         return implMulAdd(out, in, offset, len, k);
2896     }
2897 
2898     /**
2899      * Parameters validation.
2900      */
2901     private static void implMulAddCheck(int[] out, int[] in, int offset, int len, int k) {
2902         if (len > in.length) {
2903             throw new IllegalArgumentException("input length is out of bound: " + len + " > " + in.length);
2904         }
2905         if (offset < 0) {
2906             throw new IllegalArgumentException("input offset is invalid: " + offset);
2907         }
2908         if (offset > (out.length - 1)) {
2909             throw new IllegalArgumentException("input offset is out of bound: " + offset + " > " + (out.length - 1));
2910         }
2911         if (len > (out.length - offset)) {
2912             throw new IllegalArgumentException("input len is out of bound: " + len + " > " + (out.length - offset));
2913         }
2914     }
2915 
2916     /**
2917      * Java Runtime may use intrinsic for this method.
2918      */
2919     private static int implMulAdd(int[] out, int[] in, int offset, int len, int k) {
2920         long kLong = k & LONG_MASK;
2921         long carry = 0;
2922 
2923         offset = out.length-offset - 1;
2924         for (int j=len-1; j >= 0; j--) {
2925             long product = (in[j] & LONG_MASK) * kLong +
2926                            (out[offset] & LONG_MASK) + carry;
2927             out[offset--] = (int)product;
2928             carry = product >>> 32;
2929         }
2930         return (int)carry;
2931     }
2932 
2933     /**
2934      * Add one word to the number a mlen words into a. Return the resulting
2935      * carry.
2936      */
2937     static int addOne(int[] a, int offset, int mlen, int carry) {
2938         offset = a.length-1-mlen-offset;
2939         long t = (a[offset] & LONG_MASK) + (carry & LONG_MASK);


jdk/src/java.base/share/classes/java/math/BigInteger.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File