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

Print this page
rev 8880 : 8029501: BigInteger division algorithm selection heuristic is incorrect
Summary: Change Burnikel-Ziegler division heuristic to require that the dividend int-length exceed that of the divisor by a minimum amount.
Reviewed-by: TBD

*** 242,258 **** */ private static final int TOOM_COOK_SQUARE_THRESHOLD = 216; /** * The threshold value for using Burnikel-Ziegler division. If the number ! * of ints in the number are larger than this value, ! * Burnikel-Ziegler division will be used. This value is found ! * experimentally to work well. */ static final int BURNIKEL_ZIEGLER_THRESHOLD = 80; /** * The threshold value for using Schoenhage recursive base conversion. If * the number of ints in the number are larger than this value, * the Schoenhage algorithm will be used. In practice, it appears that the * Schoenhage routine is faster for any threshold down to 2, and is * relatively flat for thresholds between 2-25, so this choice may be --- 242,266 ---- */ private static final int TOOM_COOK_SQUARE_THRESHOLD = 216; /** * The threshold value for using Burnikel-Ziegler division. If the number ! * of ints in the divisor are larger than this value, Burnikel-Ziegler ! * division may be used. This value is found experimentally to work well. */ static final int BURNIKEL_ZIEGLER_THRESHOLD = 80; /** + * The offset value for using Burnikel-Ziegler division. If the number + * of ints in the divisor exceeds the Burnikel-Ziegler threshold, and the + * number of ints in the dividend is greater than the number of ints in the + * divisor plus this value, Burnikel-Ziegler division will be used. This + * value is found experimentally to work well. + */ + static final int BURNIKEL_ZIEGLER_OFFSET = 40; + + /** * The threshold value for using Schoenhage recursive base conversion. If * the number of ints in the number are larger than this value, * the Schoenhage algorithm will be used. In practice, it appears that the * Schoenhage routine is faster for any threshold down to 2, and is * relatively flat for thresholds between 2-25, so this choice may be
*** 2015,2026 **** * @param val value by which this BigInteger is to be divided. * @return {@code this / val} * @throws ArithmeticException if {@code val} is zero. */ public BigInteger divide(BigInteger val) { ! if (mag.length < BURNIKEL_ZIEGLER_THRESHOLD || ! val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD) { return divideKnuth(val); } else { return divideBurnikelZiegler(val); } } --- 2023,2034 ---- * @param val value by which this BigInteger is to be divided. * @return {@code this / val} * @throws ArithmeticException if {@code val} is zero. */ public BigInteger divide(BigInteger val) { ! if (val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD || ! mag.length - val.mag.length < BURNIKEL_ZIEGLER_OFFSET) { return divideKnuth(val); } else { return divideBurnikelZiegler(val); } }
*** 2052,2063 **** * is the initial element, and the remainder {@code (this % val)} * is the final element. * @throws ArithmeticException if {@code val} is zero. */ public BigInteger[] divideAndRemainder(BigInteger val) { ! if (mag.length < BURNIKEL_ZIEGLER_THRESHOLD || ! val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD) { return divideAndRemainderKnuth(val); } else { return divideAndRemainderBurnikelZiegler(val); } } --- 2060,2071 ---- * is the initial element, and the remainder {@code (this % val)} * is the final element. * @throws ArithmeticException if {@code val} is zero. */ public BigInteger[] divideAndRemainder(BigInteger val) { ! if (val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD || ! mag.length - val.mag.length < BURNIKEL_ZIEGLER_OFFSET) { return divideAndRemainderKnuth(val); } else { return divideAndRemainderBurnikelZiegler(val); } }
*** 2081,2092 **** * remainder computed. * @return {@code this % val} * @throws ArithmeticException if {@code val} is zero. */ public BigInteger remainder(BigInteger val) { ! if (mag.length < BURNIKEL_ZIEGLER_THRESHOLD || ! val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD) { return remainderKnuth(val); } else { return remainderBurnikelZiegler(val); } } --- 2089,2100 ---- * remainder computed. * @return {@code this % val} * @throws ArithmeticException if {@code val} is zero. */ public BigInteger remainder(BigInteger val) { ! if (val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD || ! mag.length - val.mag.length < BURNIKEL_ZIEGLER_OFFSET) { return remainderKnuth(val); } else { return remainderBurnikelZiegler(val); } }