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,11 +258,19 @@
      * 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
+    /**
+     * 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,18 +1456,26 @@
     }
 
     /**
      * 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) {