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

Print this page
rev 8866 : 4891331: BigInteger a.multiply(a) should use squaring code
Summary: Change multiply(BigInteger a) to return square() if a == this and the number of ints in the magnitude is over a threshold.
Reviewed-by: darcy, shade

*** 258,268 **** * relatively flat for thresholds between 2-25, so this choice may be * varied within this range for very small effect. */ private static final int SCHOENHAGE_BASE_CONVERSION_THRESHOLD = 8; ! //Constructors /** * Translates a byte array containing the two's-complement binary * representation of a BigInteger into a BigInteger. The input array is * assumed to be in <i>big-endian</i> byte-order: the most significant --- 258,276 ---- * relatively flat for thresholds between 2-25, so this choice may be * varied within this range for very small effect. */ private static final int SCHOENHAGE_BASE_CONVERSION_THRESHOLD = 8; ! /** ! * The threshold value for using squaring code to perform multiplication ! * of a {@code BigInteger} instance by itself. If the number of ints in ! * the number are larger than this value, {@code multiply(this)} will ! * return {@code square()}. ! */ ! private static final int MULTIPLY_SQUARE_THRESHOLD = 20; ! ! // Constructors /** * Translates a byte array containing the two's-complement binary * representation of a BigInteger into a BigInteger. The input array is * assumed to be in <i>big-endian</i> byte-order: the most significant
*** 1448,1465 **** --- 1456,1481 ---- } /** * Returns a BigInteger whose value is {@code (this * val)}. * + * @implNote An implementation may offer better algorithmic + * performance when {@code val == this}. + * * @param val value to be multiplied by this BigInteger. * @return {@code this * val} */ public BigInteger multiply(BigInteger val) { if (val.signum == 0 || signum == 0) return ZERO; int xlen = mag.length; + + if (val == this && xlen > MULTIPLY_SQUARE_THRESHOLD) { + return square(); + } + int ylen = val.mag.length; if ((xlen < KARATSUBA_THRESHOLD) || (ylen < KARATSUBA_THRESHOLD)) { int resultSign = signum == val.signum ? 1 : -1; if (val.mag.length == 1) {