Path: blob/master/test/jdk/java/math/BigInteger/LargeValueExceptions.java
41149 views
/*1* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 820069826* @summary Tests that exceptions are thrown for ops which would overflow27* @requires (sun.arch.data.model == "64" & os.maxMemory >= 4g)28* @run testng/othervm -Xmx4g LargeValueExceptions29*/30import java.math.BigInteger;31import static java.math.BigInteger.ONE;32import org.testng.annotations.Test;3334//35// The intent of this test is to probe the boundaries between overflow and36// non-overflow, principally for multiplication and squaring, specifically37// the largest values which should not overflow and the smallest values which38// should. The transition values used are not necessarily at the exact39// boundaries but should be "close." Quite a few different values were used40// experimentally before settling on the ones in this test. For multiplication41// and squaring all cases are exercised: definite overflow and non-overflow42// which can be detected "up front," and "indefinite" overflow, i.e., overflow43// which cannot be detected up front so further calculations are required.44//45// Testing negative values is unnecessary. For both multiplication and squaring46// the paths lead to the Toom-Cook algorithm where the signum is used only to47// determine the sign of the result and not in the intermediate calculations.48// This is also true for exponentiation.49//50// @Test annotations with optional element "enabled" set to "false" should51// succeed when "enabled" is set to "true" but they take too to run in the52// course of the typical regression test execution scenario.53//54public class LargeValueExceptions {55// BigInteger.MAX_MAG_LENGTH56private static final int MAX_INTS = 1 << 26;5758// Number of bits corresponding to MAX_INTS59private static final long MAX_BITS = (0xffffffffL & MAX_INTS) << 5L;6061// Half BigInteger.MAX_MAG_LENGTH62private static final int MAX_INTS_HALF = MAX_INTS / 2;6364// --- squaring ---6566// Largest no overflow determined by examining data lengths alone.67@Test(enabled=false)68public void squareNoOverflow() {69BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1).subtract(ONE);70BigInteger y = x.multiply(x);71}7273// Smallest no overflow determined by extra calculations.74@Test(enabled=false)75public void squareIndefiniteOverflowSuccess() {76BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1);77BigInteger y = x.multiply(x);78}7980// Largest overflow detected by extra calculations.81@Test(expectedExceptions=ArithmeticException.class,enabled=false)82public void squareIndefiniteOverflowFailure() {83BigInteger x = ONE.shiftLeft(16*MAX_INTS).subtract(ONE);84BigInteger y = x.multiply(x);85}8687// Smallest overflow detected by examining data lengths alone.88@Test(expectedExceptions=ArithmeticException.class)89public void squareDefiniteOverflow() {90BigInteger x = ONE.shiftLeft(16*MAX_INTS);91BigInteger y = x.multiply(x);92}9394// --- multiplication ---9596// Largest no overflow determined by examining data lengths alone.97@Test(enabled=false)98public void multiplyNoOverflow() {99final int halfMaxBits = MAX_INTS_HALF << 5;100101BigInteger x = ONE.shiftLeft(halfMaxBits).subtract(ONE);102BigInteger y = ONE.shiftLeft(halfMaxBits - 1).subtract(ONE);103BigInteger z = x.multiply(y);104}105106// Smallest no overflow determined by extra calculations.107@Test(enabled=false)108public void multiplyIndefiniteOverflowSuccess() {109BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2) - 1);110long m = MAX_BITS - x.bitLength();111112BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2) - 1);113long n = MAX_BITS - y.bitLength();114115if (m + n != MAX_BITS) {116throw new RuntimeException("Unexpected leading zero sum");117}118119BigInteger z = x.multiply(y);120}121122// Largest overflow detected by extra calculations.123@Test(expectedExceptions=ArithmeticException.class,enabled=false)124public void multiplyIndefiniteOverflowFailure() {125BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE);126long m = MAX_BITS - x.bitLength();127128BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE);129long n = MAX_BITS - y.bitLength();130131if (m + n != MAX_BITS) {132throw new RuntimeException("Unexpected leading zero sum");133}134135BigInteger z = x.multiply(y);136}137138// Smallest overflow detected by examining data lengths alone.139@Test(expectedExceptions=ArithmeticException.class)140public void multiplyDefiniteOverflow() {141// multiply by 4 as MAX_INTS_HALF refers to ints142byte[] xmag = new byte[4*MAX_INTS_HALF];143xmag[0] = (byte)0xff;144BigInteger x = new BigInteger(1, xmag);145146byte[] ymag = new byte[4*MAX_INTS_HALF + 1];147ymag[0] = (byte)0xff;148BigInteger y = new BigInteger(1, ymag);149150BigInteger z = x.multiply(y);151}152153// --- exponentiation ---154155@Test(expectedExceptions=ArithmeticException.class)156public void powOverflow() {157BigInteger.TEN.pow(Integer.MAX_VALUE);158}159160@Test(expectedExceptions=ArithmeticException.class)161public void powOverflow1() {162int shift = 20;163int exponent = 1 << shift;164BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent));165BigInteger y = x.pow(exponent);166}167168@Test(expectedExceptions=ArithmeticException.class)169public void powOverflow2() {170int shift = 20;171int exponent = 1 << shift;172BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).add(ONE);173BigInteger y = x.pow(exponent);174}175176@Test(expectedExceptions=ArithmeticException.class,enabled=false)177public void powOverflow3() {178int shift = 20;179int exponent = 1 << shift;180BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).subtract(ONE);181BigInteger y = x.pow(exponent);182}183184@Test(enabled=false)185public void powOverflow4() {186int shift = 20;187int exponent = 1 << shift;188BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent - 1)).add(ONE);189BigInteger y = x.pow(exponent);190}191}192193194