Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/Math/ExactArithTests.java
38812 views
/*1* Copyright (c) 2012, 2013, 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*/2223import java.math.BigInteger;2425/**26* @test Test for Math.*Exact integer and long methods.27* @bug 670839828* @summary Basic tests for Math exact arithmetic operations.29*30* @author Roger Riggs31*/32public class ExactArithTests {3334/**35* The count of test errors.36*/37private static int errors = 0;3839/**40* @param args the command line arguments41*/42public static void main(String[] args) {43testIntegerExact();44testLongExact();4546if (errors > 0) {47throw new RuntimeException(errors + " errors found in ExactArithTests.");48}49}5051static void fail(String message) {52errors++;53System.err.println(message);54}5556/**57* Test Math.addExact, multiplyExact, subtractExact, toIntValue methods58* with {@code int} arguments.59*/60static void testIntegerExact() {61testIntegerExact(0, 0);62testIntegerExact(1, 1);63testIntegerExact(1, -1);64testIntegerExact(-1, 1);65testIntegerExact(1000, 2000);6667testIntegerExact(Integer.MIN_VALUE, Integer.MIN_VALUE);68testIntegerExact(Integer.MAX_VALUE, Integer.MAX_VALUE);69testIntegerExact(Integer.MIN_VALUE, 1);70testIntegerExact(Integer.MAX_VALUE, 1);71testIntegerExact(Integer.MIN_VALUE, 2);72testIntegerExact(Integer.MAX_VALUE, 2);73testIntegerExact(Integer.MIN_VALUE, -1);74testIntegerExact(Integer.MAX_VALUE, -1);75testIntegerExact(Integer.MIN_VALUE, -2);76testIntegerExact(Integer.MAX_VALUE, -2);7778}7980/**81* Test exact arithmetic by comparing with the same operations using long82* and checking that the result is the same as the integer truncation.83* Errors are reported with {@link fail}.84*85* @param x first parameter86* @param y second parameter87*/88static void testIntegerExact(int x, int y) {89try {90// Test addExact91int sum = Math.addExact(x, y);92long sum2 = (long) x + (long) y;93if ((int) sum2 != sum2) {94fail("FAIL: int Math.addExact(" + x + " + " + y + ") = " + sum + "; expected Arithmetic exception");95} else if (sum != sum2) {96fail("FAIL: long Math.addExact(" + x + " + " + y + ") = " + sum + "; expected: " + sum2);97}98} catch (ArithmeticException ex) {99long sum2 = (long) x + (long) y;100if ((int) sum2 == sum2) {101fail("FAIL: int Math.addExact(" + x + " + " + y + ")" + "; Unexpected exception: " + ex);102103}104}105106try {107// Test subtractExact108int diff = Math.subtractExact(x, y);109long diff2 = (long) x - (long) y;110if ((int) diff2 != diff2) {111fail("FAIL: int Math.subtractExact(" + x + " - " + y + ") = " + diff + "; expected: " + diff2);112}113114} catch (ArithmeticException ex) {115long diff2 = (long) x - (long) y;116if ((int) diff2 == diff2) {117fail("FAIL: int Math.subtractExact(" + x + " - " + y + ")" + "; Unexpected exception: " + ex);118}119}120121try {122// Test multiplyExact123int product = Math.multiplyExact(x, y);124long m2 = (long) x * (long) y;125if ((int) m2 != m2) {126fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ") = " + product + "; expected: " + m2);127}128} catch (ArithmeticException ex) {129long m2 = (long) x * (long) y;130if ((int) m2 == m2) {131fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);132}133}134try {135// Test incrementExact136int inc = Math.incrementExact(x);137long inc2 = (long) x + 1L;138if ((int) inc2 != inc2) {139fail("FAIL: int Math.incrementExact(" + x + ") = " + inc + "; expected Arithmetic exception");140} else if (inc != inc2) {141fail("FAIL: long Math.incrementExact(" + x + ") = " + inc + "; expected: " + inc2);142}143} catch (ArithmeticException ex) {144long inc2 = (long) x + 1L;145if ((int) inc2 == inc2) {146fail("FAIL: int Math.incrementExact(" + x + ")" + "; Unexpected exception: " + ex);147148}149}150151try {152// Test decrementExact153int dec = Math.decrementExact(x);154long dec2 = (long) x - 1L;155if ((int) dec2 != dec2) {156fail("FAIL: int Math.decrementExact(" + x + ") = " + dec + "; expected Arithmetic exception");157} else if (dec != dec2) {158fail("FAIL: long Math.decrementExact(" + x + ") = " + dec + "; expected: " + dec2);159}160} catch (ArithmeticException ex) {161long dec2 = (long) x - 1L;162if ((int) dec2 == dec2) {163fail("FAIL: int Math.decrementExact(" + x + ")" + "; Unexpected exception: " + ex);164165}166}167168try {169// Test negateExact170int neg = Math.negateExact(x);171long neg2 = -((long)x) ;172if ((int) neg2 != neg2) {173fail("FAIL: int Math.negateExact(" + x + ") = " + neg + "; expected Arithmetic exception");174} else if (neg != neg2) {175fail("FAIL: long Math.negateExact(" + x + ") = " + neg + "; expected: " + neg2);176}177} catch (ArithmeticException ex) {178long neg2 = (long) x - 1L;179if ((int) neg2 == neg2) {180fail("FAIL: int Math.negateExact(" + x + ")" + "; Unexpected exception: " + ex);181182}183}184}185186/**187* Test Math.addExact, multiplyExact, subtractExact, toIntExact methods188* with {@code long} arguments.189*/190static void testLongExact() {191testLongExactTwice(0, 0);192testLongExactTwice(1, 1);193testLongExactTwice(1, -1);194testLongExactTwice(1000, 2000);195196testLongExactTwice(Long.MIN_VALUE, Long.MIN_VALUE);197testLongExactTwice(Long.MAX_VALUE, Long.MAX_VALUE);198testLongExactTwice(Long.MIN_VALUE, 1);199testLongExactTwice(Long.MAX_VALUE, 1);200testLongExactTwice(Long.MIN_VALUE, 2);201testLongExactTwice(Long.MAX_VALUE, 2);202testLongExactTwice(Long.MIN_VALUE, -1);203testLongExactTwice(Long.MAX_VALUE, -1);204testLongExactTwice(Long.MIN_VALUE, -2);205testLongExactTwice(Long.MAX_VALUE, -2);206testLongExactTwice(Long.MIN_VALUE/2, 2);207testLongExactTwice(Long.MAX_VALUE, 2);208testLongExactTwice(Integer.MAX_VALUE, Integer.MAX_VALUE);209testLongExactTwice(Integer.MAX_VALUE, -Integer.MAX_VALUE);210testLongExactTwice(Integer.MAX_VALUE+1, Integer.MAX_VALUE+1);211testLongExactTwice(Integer.MAX_VALUE+1, -Integer.MAX_VALUE+1);212testLongExactTwice(Integer.MIN_VALUE-1, Integer.MIN_VALUE-1);213testLongExactTwice(Integer.MIN_VALUE-1, -Integer.MIN_VALUE-1);214testLongExactTwice(Integer.MIN_VALUE/2, 2);215216}217218/**219* Test each of the exact operations with the arguments and220* with the arguments reversed.221* @param x222* @param y223*/224static void testLongExactTwice(long x, long y) {225testLongExact(x, y);226testLongExact(y, x);227}228229230/**231* Test long exact arithmetic by comparing with the same operations using BigInteger232* and checking that the result is the same as the long truncation.233* Errors are reported with {@link fail}.234*235* @param x first parameter236* @param y second parameter237*/238static void testLongExact(long x, long y) {239BigInteger resultBig = null;240final BigInteger xBig = BigInteger.valueOf(x);241final BigInteger yBig = BigInteger.valueOf(y);242try {243// Test addExact244resultBig = xBig.add(yBig);245long sum = Math.addExact(x, y);246checkResult("long Math.addExact", x, y, sum, resultBig);247} catch (ArithmeticException ex) {248if (inLongRange(resultBig)) {249fail("FAIL: long Math.addExact(" + x + " + " + y + "); Unexpected exception: " + ex);250}251}252253try {254// Test subtractExact255resultBig = xBig.subtract(yBig);256long diff = Math.subtractExact(x, y);257checkResult("long Math.subtractExact", x, y, diff, resultBig);258} catch (ArithmeticException ex) {259if (inLongRange(resultBig)) {260fail("FAIL: long Math.subtractExact(" + x + " - " + y + ")" + "; Unexpected exception: " + ex);261}262}263264try {265// Test multiplyExact266resultBig = xBig.multiply(yBig);267long product = Math.multiplyExact(x, y);268checkResult("long Math.multiplyExact", x, y, product, resultBig);269} catch (ArithmeticException ex) {270if (inLongRange(resultBig)) {271fail("FAIL: long Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);272}273}274275try {276// Test incrementExact277resultBig = xBig.add(BigInteger.ONE);278long inc = Math.incrementExact(x);279checkResult("long Math.incrementExact", x, 1L, inc, resultBig);280} catch (ArithmeticException ex) {281if (inLongRange(resultBig)) {282fail("FAIL: long Math.incrementExact(" + x + "); Unexpected exception: " + ex);283}284}285286try {287// Test decrementExact288resultBig = xBig.subtract(BigInteger.ONE);289long dec = Math.decrementExact(x);290checkResult("long Math.decrementExact", x, 1L, dec, resultBig);291} catch (ArithmeticException ex) {292if (inLongRange(resultBig)) {293fail("FAIL: long Math.decrementExact(" + x + "); Unexpected exception: " + ex);294}295}296297try {298// Test negateExact299resultBig = xBig.negate();300long dec = Math.negateExact(x);301checkResult("long Math.negateExact", x, 0L, dec, resultBig);302} catch (ArithmeticException ex) {303if (inLongRange(resultBig)) {304fail("FAIL: long Math.negateExact(" + x + "); Unexpected exception: " + ex);305}306}307308try {309// Test toIntExact310int value = Math.toIntExact(x);311if ((long)value != x) {312fail("FAIL: " + "long Math.toIntExact" + "(" + x + ") = " + value + "; expected an arithmetic exception: ");313}314} catch (ArithmeticException ex) {315if (resultBig.bitLength() <= 32) {316fail("FAIL: long Math.toIntExact(" + x + ")" + "; Unexpected exception: " + ex);317}318}319320}321322/**323* Compare the expected and actual results.324* @param message message for the error325* @param x first argument326* @param y second argument327* @param result actual result value328* @param expected expected result value329*/330static void checkResult(String message, long x, long y, long result, BigInteger expected) {331BigInteger resultBig = BigInteger.valueOf(result);332if (!inLongRange(expected)) {333fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result + "; expected an arithmetic exception: ");334} else if (!resultBig.equals(expected)) {335fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result + "; expected " + expected);336}337}338339/**340* Check if the value fits in 64 bits (a long).341* @param value342* @return true if the value fits in 64 bits (including the sign).343*/344static boolean inLongRange(BigInteger value) {345return value.bitLength() <= 63;346}347}348349350