undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
327
test/jdk/java/math/BigDecimal/AddTests.java
Normal file
327
test/jdk/java/math/BigDecimal/AddTests.java
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
/*
|
||||
* Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6362557 8200698
|
||||
* @summary Some tests of add(BigDecimal, mc)
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import static java.math.BigDecimal.*;
|
||||
import java.util.Set;
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class AddTests {
|
||||
|
||||
private static Set<RoundingMode> nonExactRoundingModes =
|
||||
EnumSet.complementOf(EnumSet.of(RoundingMode.UNNECESSARY));
|
||||
|
||||
/**
|
||||
* Test for some simple additions, particularly, it will test
|
||||
* the overflow case.
|
||||
*/
|
||||
private static int simpleTests() {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal[] bd1 = {
|
||||
new BigDecimal(new BigInteger("7812404666936930160"), 11),
|
||||
new BigDecimal(new BigInteger("7812404666936930160"), 12),
|
||||
new BigDecimal(new BigInteger("7812404666936930160"), 13),
|
||||
};
|
||||
BigDecimal bd2 = new BigDecimal(new BigInteger("2790000"), 1);
|
||||
BigDecimal[] expectedResult = {
|
||||
new BigDecimal("78403046.66936930160"),
|
||||
new BigDecimal("8091404.666936930160"),
|
||||
new BigDecimal("1060240.4666936930160"),
|
||||
};
|
||||
for (int i = 0; i < bd1.length; i++) {
|
||||
if (!bd1[i].add(bd2).equals(expectedResult[i]))
|
||||
failures++;
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for extreme value of scale and rounding precision that
|
||||
* could cause integer overflow in right-shift-into-sticky-bit
|
||||
* computations.
|
||||
*/
|
||||
private static int extremaTests() {
|
||||
int failures = 0;
|
||||
|
||||
failures += addWithoutException(valueOf(1, -Integer.MAX_VALUE),
|
||||
valueOf(2, Integer.MAX_VALUE), null);
|
||||
failures += addWithoutException(valueOf(1, -Integer.MAX_VALUE),
|
||||
valueOf(-2, Integer.MAX_VALUE), null);
|
||||
return failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print sum of b1 and b2; correct result will not throw an
|
||||
* exception.
|
||||
*/
|
||||
private static int addWithoutException(BigDecimal b1, BigDecimal b2, MathContext mc) {
|
||||
if (mc == null)
|
||||
mc = new MathContext(2, RoundingMode.DOWN);
|
||||
|
||||
try {
|
||||
BigDecimal sum = b1.add(b2, mc);
|
||||
printAddition(b1, b2, sum.toString());
|
||||
return 0;
|
||||
} catch(ArithmeticException ae) {
|
||||
printAddition(b1, b2, "Exception!");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test combinations of operands that may meet the condensation
|
||||
* criteria when rounded to different precisions.
|
||||
*/
|
||||
private static int roundingGradationTests() {
|
||||
int failures = 0;
|
||||
|
||||
failures += roundAway(new BigDecimal("1234e100"),
|
||||
new BigDecimal( "1234e97"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1234e100"),
|
||||
new BigDecimal( "1234e96"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1234e100"),
|
||||
new BigDecimal( "1234e95"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1234e100"),
|
||||
new BigDecimal( "1234e94"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1234e100"),
|
||||
new BigDecimal( "1234e93"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1234e100"),
|
||||
new BigDecimal( "1234e92"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1234e100"),
|
||||
new BigDecimal("1234e50"));
|
||||
|
||||
|
||||
failures += roundAway(new BigDecimal("1000e100"),
|
||||
new BigDecimal( "1234e97"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1000e100"),
|
||||
new BigDecimal( "1234e96"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1000e100"),
|
||||
new BigDecimal( "1234e95"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1000e100"),
|
||||
new BigDecimal( "1234e94"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1000e100"),
|
||||
new BigDecimal( "1234e93"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1000e100"),
|
||||
new BigDecimal( "1234e92"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1000e100"),
|
||||
new BigDecimal("1234e50"));
|
||||
|
||||
|
||||
|
||||
failures += roundAway(new BigDecimal("1999e100"),
|
||||
new BigDecimal( "1234e97"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1999e100"),
|
||||
new BigDecimal( "1234e96"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1999e100"),
|
||||
new BigDecimal( "1234e95"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1999e100"),
|
||||
new BigDecimal( "1234e94"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1999e100"),
|
||||
new BigDecimal( "1234e93"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1999e100"),
|
||||
new BigDecimal( "1234e92"));
|
||||
|
||||
failures += roundAway(new BigDecimal("1999e100"),
|
||||
new BigDecimal("1234e50"));
|
||||
|
||||
|
||||
|
||||
failures += roundAway(new BigDecimal("9999e100"),
|
||||
new BigDecimal( "1234e97"));
|
||||
|
||||
failures += roundAway(new BigDecimal("9999e100"),
|
||||
new BigDecimal( "1234e96"));
|
||||
|
||||
failures += roundAway(new BigDecimal("9999e100"),
|
||||
new BigDecimal( "1234e95"));
|
||||
|
||||
failures += roundAway(new BigDecimal("9999e100"),
|
||||
new BigDecimal( "1234e94"));
|
||||
|
||||
failures += roundAway(new BigDecimal("9999e100"),
|
||||
new BigDecimal( "1234e93"));
|
||||
|
||||
failures += roundAway(new BigDecimal("9999e100"),
|
||||
new BigDecimal( "1234e92"));
|
||||
|
||||
failures += roundAway(new BigDecimal("9999e100"),
|
||||
new BigDecimal("1234e50"));
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static void printAddition(BigDecimal b1, BigDecimal b2, String s) {
|
||||
System.out.println("" + b1+ "\t+\t" + b2 + "\t=\t" + s);
|
||||
}
|
||||
|
||||
private static int roundAway(BigDecimal b1, BigDecimal b2) {
|
||||
int failures = 0;
|
||||
|
||||
b1.precision();
|
||||
b2.precision();
|
||||
|
||||
BigDecimal b1_negate = b1.negate();
|
||||
BigDecimal b2_negate = b2.negate();
|
||||
|
||||
b1_negate.precision();
|
||||
b2_negate.precision();
|
||||
|
||||
failures += roundAway1(b1, b2);
|
||||
failures += roundAway1(b1, b2_negate);
|
||||
failures += roundAway1(b1_negate, b2);
|
||||
failures += roundAway1(b1_negate, b2_negate);
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int roundAway1(BigDecimal b1, BigDecimal b2) {
|
||||
int failures = 0;
|
||||
failures += roundAway0(b1, b2);
|
||||
failures += roundAway0(b2, b1);
|
||||
return failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare b1.add(b2, mc) with b1.add(b2).round(mc) for a variety
|
||||
* of MathContexts.
|
||||
*/
|
||||
private static int roundAway0(BigDecimal b1, BigDecimal b2) {
|
||||
int failures = 0;
|
||||
BigDecimal exactSum = b1.add(b2);
|
||||
|
||||
for(int precision = 1 ; precision < exactSum.precision()+2; precision++) {
|
||||
for(RoundingMode rm : nonExactRoundingModes) {
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
BigDecimal roundedExactSum = exactSum.round(mc);
|
||||
|
||||
try {
|
||||
BigDecimal sum = b1.add(b2, mc);
|
||||
|
||||
if (!roundedExactSum.equals(sum) ) {
|
||||
failures++;
|
||||
System.out.println("Exact sum " + exactSum +
|
||||
"\trounded by " + mc +
|
||||
"\texpected: " + roundedExactSum + " got: ");
|
||||
printAddition(b1, b2, sum.toString());
|
||||
}
|
||||
// else {
|
||||
// System.out.print(mc + "\t");
|
||||
// printAddition(b1, b2, sum.toString());
|
||||
// }
|
||||
|
||||
} catch (ArithmeticException ae) {
|
||||
printAddition(b1, b2, "Exception!");
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify calling the precision method should not change the
|
||||
* computed result.
|
||||
*/
|
||||
private static int precisionConsistencyTest() {
|
||||
int failures = 0;
|
||||
MathContext mc = new MathContext(1,RoundingMode.DOWN);
|
||||
BigDecimal a = BigDecimal.valueOf(1999, -1); //value is equivalent to 19990
|
||||
|
||||
BigDecimal sum1 = a.add(BigDecimal.ONE, mc);
|
||||
a.precision();
|
||||
BigDecimal sum2 = a.add(BigDecimal.ONE, mc);
|
||||
|
||||
if (!sum1.equals(sum2)) {
|
||||
failures ++;
|
||||
System.out.println("Unequal sums after calling precision!");
|
||||
System.out.print("Before:\t");
|
||||
printAddition(a, BigDecimal.ONE, sum1.toString());
|
||||
|
||||
System.out.print("After:\t");
|
||||
printAddition(a, BigDecimal.ONE, sum2.toString());
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int arithmeticExceptionTest() {
|
||||
int failures = 0;
|
||||
BigDecimal x;
|
||||
try {
|
||||
//
|
||||
// The string representation "1e2147483647", which is equivalent
|
||||
// to 10^Integer.MAX_VALUE, is used to create an augend with an
|
||||
// unscaled value of 1 and a scale of -Integer.MAX_VALUE. The
|
||||
// addend "1" has an unscaled value of 1 with a scale of 0. The
|
||||
// addition is performed exactly and is specified to have a
|
||||
// preferred scale of max(-Integer.MAX_VALUE, 0). As the scale
|
||||
// of the result is 0, a value with Integer.MAX_VALUE + 1 digits
|
||||
// would need to be created. Therefore the next statement is
|
||||
// expected to overflow with an ArithmeticException.
|
||||
//
|
||||
x = new BigDecimal("1e2147483647").add(new BigDecimal(1));
|
||||
failures++;
|
||||
} catch (ArithmeticException ae) {
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += extremaTests();
|
||||
failures += roundingGradationTests();
|
||||
failures += precisionConsistencyTest();
|
||||
failures += arithmeticExceptionTest();
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing rounding add.");
|
||||
}
|
||||
}
|
||||
}
|
||||
115
test/jdk/java/math/BigDecimal/CompareToTests.java
Normal file
115
test/jdk/java/math/BigDecimal/CompareToTests.java
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6473768
|
||||
* @summary Tests of BigDecimal.compareTo
|
||||
*/
|
||||
import java.math.*;
|
||||
import static java.math.BigDecimal.*;
|
||||
|
||||
public class CompareToTests {
|
||||
private static int compareToTests() {
|
||||
int failures = 0;
|
||||
|
||||
final BigDecimal MINUS_ONE = BigDecimal.ONE.negate();
|
||||
|
||||
// First operand, second operand, expected compareTo result
|
||||
BigDecimal [][] testCases = {
|
||||
// Basics
|
||||
{valueOf(0), valueOf(0), ZERO},
|
||||
{valueOf(0), valueOf(1), MINUS_ONE},
|
||||
{valueOf(1), valueOf(2), MINUS_ONE},
|
||||
{valueOf(2), valueOf(1), ONE},
|
||||
{valueOf(10), valueOf(10), ZERO},
|
||||
|
||||
// Significands would compare differently than scaled value
|
||||
{valueOf(2,1), valueOf(2), MINUS_ONE},
|
||||
{valueOf(2,-1), valueOf(2), ONE},
|
||||
{valueOf(1,1), valueOf(2), MINUS_ONE},
|
||||
{valueOf(1,-1), valueOf(2), ONE},
|
||||
{valueOf(5,-1), valueOf(2), ONE},
|
||||
|
||||
// Boundary and near boundary values
|
||||
{valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO},
|
||||
{valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
|
||||
{valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
{valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
|
||||
{valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
{valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MAX_VALUE), ONE},
|
||||
|
||||
{valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
{valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MAX_VALUE), ZERO},
|
||||
|
||||
{valueOf(Long.MAX_VALUE), valueOf(Long.MIN_VALUE), ONE},
|
||||
{valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE},
|
||||
|
||||
{valueOf(Long.MAX_VALUE-1), valueOf(Long.MIN_VALUE), ONE},
|
||||
{valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MIN_VALUE), ONE},
|
||||
|
||||
{valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO},
|
||||
{valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE},
|
||||
|
||||
{valueOf(Long.MIN_VALUE+1), valueOf(Long.MIN_VALUE), ONE},
|
||||
{valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MIN_VALUE), ONE},
|
||||
};
|
||||
|
||||
for (BigDecimal[] testCase : testCases) {
|
||||
BigDecimal a = testCase[0];
|
||||
BigDecimal a_negate = a.negate();
|
||||
BigDecimal b = testCase[1];
|
||||
BigDecimal b_negate = b.negate();
|
||||
int expected = testCase[2].intValue();
|
||||
|
||||
failures += compareToTest(a, b, expected);
|
||||
failures += compareToTest(a_negate, b_negate, -expected);
|
||||
}
|
||||
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int compareToTest(BigDecimal a, BigDecimal b, int expected) {
|
||||
int result = a.compareTo(b);
|
||||
int failed = (result==expected) ? 0 : 1;
|
||||
if (failed == 1) {
|
||||
System.err.println("(" + a + ").compareTo(" + b + ") => " + result +
|
||||
"\n\tExpected " + expected);
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += compareToTests();
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing exact compareTo.");
|
||||
}
|
||||
}
|
||||
}
|
||||
82
test/jdk/java/math/BigDecimal/Constructor.java
Normal file
82
test/jdk/java/math/BigDecimal/Constructor.java
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4259453 8200698
|
||||
* @summary Test constructors of BigDecimal
|
||||
* @library ..
|
||||
* @run junit Constructor
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class Constructor {
|
||||
@Test
|
||||
public void stringConstructor() {
|
||||
Assertions.assertThrows(NumberFormatException.class, () -> {
|
||||
BigDecimal bd = new BigDecimal("1.2e");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void charArrayConstructorNegativeOffset() {
|
||||
Assertions.assertThrows(NumberFormatException.class, () -> {
|
||||
BigDecimal bd = new BigDecimal(new char[5], -1, 4, null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void charArrayConstructorNegativeLength() {
|
||||
Assertions.assertThrows(NumberFormatException.class, () -> {
|
||||
BigDecimal bd = new BigDecimal(new char[5], 0, -1, null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void charArrayConstructorIntegerOverflow() {
|
||||
Assertions.assertThrows(NumberFormatException.class, () -> {
|
||||
try {
|
||||
BigDecimal bd = new BigDecimal(new char[5], Integer.MAX_VALUE - 5,
|
||||
6, null);
|
||||
} catch (NumberFormatException nfe) {
|
||||
if (nfe.getCause() instanceof IndexOutOfBoundsException) {
|
||||
throw new RuntimeException
|
||||
("NumberFormatException should not have a cause");
|
||||
} else {
|
||||
throw nfe;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void charArrayConstructorIndexOutOfBounds() {
|
||||
Assertions.assertThrows(NumberFormatException.class, () -> {
|
||||
BigDecimal bd = new BigDecimal(new char[5], 1, 5, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
64
test/jdk/java/math/BigDecimal/ConstructorUnscaledValue.java
Normal file
64
test/jdk/java/math/BigDecimal/ConstructorUnscaledValue.java
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8282252
|
||||
* @summary Test constructors of BigDecimal to replace BigInteger subclasses
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
|
||||
public class ConstructorUnscaledValue {
|
||||
public static void main(String... args) {
|
||||
TestBigInteger tbi = new TestBigInteger(BigInteger.ONE);
|
||||
// Create BigDecimal's using each of the three constructors
|
||||
// with guards on the class of unscaledValue
|
||||
BigDecimal[] values = {
|
||||
new BigDecimal(tbi),
|
||||
new BigDecimal(tbi, 2),
|
||||
new BigDecimal(tbi, 3, MathContext.DECIMAL32),
|
||||
};
|
||||
|
||||
for (var bd : values) {
|
||||
BigInteger unscaledValue = bd.unscaledValue();
|
||||
if (unscaledValue.getClass() != BigInteger.class) {
|
||||
throw new RuntimeException("Bad class for unscaledValue");
|
||||
}
|
||||
if (!unscaledValue.equals(BigInteger.ONE)) {
|
||||
throw new RuntimeException("Bad value for unscaledValue");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestBigInteger extends BigInteger {
|
||||
public TestBigInteger(BigInteger bi) {
|
||||
super(bi.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return java.util.Arrays.toString(toByteArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
5797
test/jdk/java/math/BigDecimal/DivideMcTests.java
Normal file
5797
test/jdk/java/math/BigDecimal/DivideMcTests.java
Normal file
File diff suppressed because it is too large
Load diff
426
test/jdk/java/math/BigDecimal/DivideTests.java
Normal file
426
test/jdk/java/math/BigDecimal/DivideTests.java
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4851776 4907265 6177836 6876282 8066842
|
||||
* @summary Some tests for the divide methods.
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import static java.math.BigDecimal.*;
|
||||
|
||||
public class DivideTests {
|
||||
|
||||
// Preliminary exact divide method; could be used for comparison
|
||||
// purposes.
|
||||
BigDecimal anotherDivide(BigDecimal dividend, BigDecimal divisor) {
|
||||
/*
|
||||
* Handle zero cases first.
|
||||
*/
|
||||
if (divisor.signum() == 0) { // x/0
|
||||
if (dividend.signum() == 0) // 0/0
|
||||
throw new ArithmeticException("Division undefined"); // NaN
|
||||
throw new ArithmeticException("Division by zero");
|
||||
}
|
||||
if (dividend.signum() == 0) // 0/y
|
||||
return BigDecimal.ZERO;
|
||||
else {
|
||||
/*
|
||||
* Determine if there is a result with a terminating
|
||||
* decimal expansion. Putting aside overflow and
|
||||
* underflow considerations, the existance of an exact
|
||||
* result only depends on the ratio of the intVal's of the
|
||||
* dividend (i.e. this) and divisor since the scales
|
||||
* of the argument just affect where the decimal point
|
||||
* lies.
|
||||
*
|
||||
* For the ratio of (a = this.intVal) and (b =
|
||||
* divisor.intVal) to have a finite decimal expansion,
|
||||
* once a/b is put in lowest terms, b must be equal to
|
||||
* (2^i)*(5^j) for some integer i,j >= 0. Therefore, we
|
||||
* first compute to see if b_prime =(b/gcd(a,b)) is equal
|
||||
* to (2^i)*(5^j).
|
||||
*/
|
||||
BigInteger TWO = BigInteger.valueOf(2);
|
||||
BigInteger FIVE = BigInteger.valueOf(5);
|
||||
BigInteger TEN = BigInteger.valueOf(10);
|
||||
|
||||
BigInteger divisorIntvalue = divisor.scaleByPowerOfTen(divisor.scale()).toBigInteger().abs();
|
||||
BigInteger dividendIntvalue = dividend.scaleByPowerOfTen(dividend.scale()).toBigInteger().abs();
|
||||
|
||||
BigInteger b_prime = divisorIntvalue.divide(dividendIntvalue.gcd(divisorIntvalue));
|
||||
|
||||
boolean goodDivisor = false;
|
||||
int i=0, j=0;
|
||||
|
||||
badDivisor: {
|
||||
while(! b_prime.equals(BigInteger.ONE) ) {
|
||||
int b_primeModTen = b_prime.mod(TEN).intValue() ;
|
||||
|
||||
switch(b_primeModTen) {
|
||||
case 0:
|
||||
// b_prime divisible by 10=2*5, increment i and j
|
||||
i++;
|
||||
j++;
|
||||
b_prime = b_prime.divide(TEN);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// b_prime divisible by 5, increment j
|
||||
j++;
|
||||
b_prime = b_prime.divide(FIVE);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 8:
|
||||
// b_prime divisible by 2, increment i
|
||||
i++;
|
||||
b_prime = b_prime.divide(TWO);
|
||||
break;
|
||||
|
||||
default: // hit something we shouldn't have
|
||||
b_prime = BigInteger.ONE; // terminate loop
|
||||
break badDivisor;
|
||||
}
|
||||
}
|
||||
|
||||
goodDivisor = true;
|
||||
}
|
||||
|
||||
if( ! goodDivisor ) {
|
||||
throw new ArithmeticException("Non terminating decimal expansion");
|
||||
}
|
||||
else {
|
||||
// What is a rule for determining how many digits are
|
||||
// needed? Once that is determined, cons up a new
|
||||
// MathContext object and pass it on to the divide(bd,
|
||||
// mc) method; precision == ?, roundingMode is unnecessary.
|
||||
|
||||
// Are we sure this is the right scale to use? Should
|
||||
// also determine a precision-based method.
|
||||
MathContext mc = new MathContext(dividend.precision() +
|
||||
(int)Math.ceil(
|
||||
10.0*divisor.precision()/3.0),
|
||||
RoundingMode.UNNECESSARY);
|
||||
// Should do some more work here to rescale, etc.
|
||||
return dividend.divide(divisor, mc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int powersOf2and5() {
|
||||
int failures = 0;
|
||||
|
||||
for(int i = 0; i < 6; i++) {
|
||||
int powerOf2 = (int)StrictMath.pow(2.0, i);
|
||||
|
||||
for(int j = 0; j < 6; j++) {
|
||||
int powerOf5 = (int)StrictMath.pow(5.0, j);
|
||||
int product;
|
||||
|
||||
BigDecimal bd;
|
||||
|
||||
try {
|
||||
bd = BigDecimal.ONE.divide(new BigDecimal(product=powerOf2*powerOf5));
|
||||
} catch (ArithmeticException e) {
|
||||
failures++;
|
||||
System.err.println((new BigDecimal(powerOf2)).toString() + " / " +
|
||||
(new BigDecimal(powerOf5)).toString() + " threw an exception.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
bd = new BigDecimal(powerOf2).divide(new BigDecimal(powerOf5));
|
||||
} catch (ArithmeticException e) {
|
||||
failures++;
|
||||
System.err.println((new BigDecimal(powerOf2)).toString() + " / " +
|
||||
(new BigDecimal(powerOf5)).toString() + " threw an exception.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
bd = new BigDecimal(powerOf5).divide(new BigDecimal(powerOf2));
|
||||
} catch (ArithmeticException e) {
|
||||
failures++;
|
||||
System.err.println((new BigDecimal(powerOf5)).toString() + " / " +
|
||||
(new BigDecimal(powerOf2)).toString() + " threw an exception.");
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static int nonTerminating() {
|
||||
int failures = 0;
|
||||
int[] primes = {1, 3, 7, 13, 17};
|
||||
|
||||
// For each pair of prime products, verify the ratio of
|
||||
// non-equal products has a non-terminating expansion.
|
||||
|
||||
for(int i = 0; i < primes.length; i++) {
|
||||
for(int j = i+1; j < primes.length; j++) {
|
||||
|
||||
for(int m = 0; m < primes.length; m++) {
|
||||
for(int n = m+1; n < primes.length; n++) {
|
||||
int dividend = primes[i] * primes[j];
|
||||
int divisor = primes[m] * primes[n];
|
||||
|
||||
if ( ((dividend/divisor) * divisor) != dividend ) {
|
||||
try {
|
||||
BigDecimal quotient = (new BigDecimal(dividend).
|
||||
divide(new BigDecimal(divisor)));
|
||||
failures++;
|
||||
System.err.println("Exact quotient " + quotient.toString() +
|
||||
" returned for non-terminating fraction " +
|
||||
dividend + " / " + divisor + ".");
|
||||
}
|
||||
catch (ArithmeticException e) {
|
||||
; // Correct result
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static int properScaleTests(){
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal[][] testCases = {
|
||||
{new BigDecimal("1"), new BigDecimal("5"), new BigDecimal("2e-1")},
|
||||
{new BigDecimal("1"), new BigDecimal("50e-1"), new BigDecimal("2e-1")},
|
||||
{new BigDecimal("10e-1"), new BigDecimal("5"), new BigDecimal("2e-1")},
|
||||
{new BigDecimal("1"), new BigDecimal("500e-2"), new BigDecimal("2e-1")},
|
||||
{new BigDecimal("100e-2"), new BigDecimal("5"), new BigDecimal("20e-2")},
|
||||
{new BigDecimal("1"), new BigDecimal("32"), new BigDecimal("3125e-5")},
|
||||
{new BigDecimal("1"), new BigDecimal("64"), new BigDecimal("15625e-6")},
|
||||
{new BigDecimal("1.0000000"), new BigDecimal("64"), new BigDecimal("156250e-7")},
|
||||
};
|
||||
|
||||
|
||||
for(BigDecimal[] tc : testCases) {
|
||||
BigDecimal quotient;
|
||||
if (! (quotient = tc[0].divide(tc[1])).equals(tc[2]) ) {
|
||||
failures++;
|
||||
System.err.println("Unexpected quotient from " + tc[0] + " / " + tc[1] +
|
||||
"; expected " + tc[2] + " got " + quotient);
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static int trailingZeroTests() {
|
||||
int failures = 0;
|
||||
|
||||
MathContext mc = new MathContext(3, RoundingMode.FLOOR);
|
||||
BigDecimal[][] testCases = {
|
||||
{new BigDecimal("19"), new BigDecimal("100"), new BigDecimal("0.19")},
|
||||
{new BigDecimal("21"), new BigDecimal("110"), new BigDecimal("0.190")},
|
||||
};
|
||||
|
||||
for(BigDecimal[] tc : testCases) {
|
||||
BigDecimal quotient;
|
||||
if (! (quotient = tc[0].divide(tc[1], mc)).equals(tc[2]) ) {
|
||||
failures++;
|
||||
System.err.println("Unexpected quotient from " + tc[0] + " / " + tc[1] +
|
||||
"; expected " + tc[2] + " got " + quotient);
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static int scaledRoundedDivideTests() {
|
||||
int failures = 0;
|
||||
// Tests of the traditional scaled divide under different
|
||||
// rounding modes.
|
||||
|
||||
// Encode rounding mode and scale for the divide in a
|
||||
// BigDecimal with the significand equal to the rounding mode
|
||||
// and the scale equal to the number's scale.
|
||||
|
||||
// {dividend, dividisor, rounding, quotient}
|
||||
BigDecimal a = new BigDecimal("31415");
|
||||
BigDecimal a_minus = a.negate();
|
||||
BigDecimal b = new BigDecimal("10000");
|
||||
|
||||
BigDecimal c = new BigDecimal("31425");
|
||||
BigDecimal c_minus = c.negate();
|
||||
|
||||
// Ad hoc tests
|
||||
BigDecimal d = new BigDecimal(new BigInteger("-37361671119238118911893939591735"), 10);
|
||||
BigDecimal e = new BigDecimal(new BigInteger("74723342238476237823787879183470"), 15);
|
||||
|
||||
BigDecimal[][] testCases = {
|
||||
{a, b, BigDecimal.valueOf(ROUND_UP, 3), new BigDecimal("3.142")},
|
||||
{a_minus, b, BigDecimal.valueOf(ROUND_UP, 3), new BigDecimal("-3.142")},
|
||||
|
||||
{a, b, BigDecimal.valueOf(ROUND_DOWN, 3), new BigDecimal("3.141")},
|
||||
{a_minus, b, BigDecimal.valueOf(ROUND_DOWN, 3), new BigDecimal("-3.141")},
|
||||
|
||||
{a, b, BigDecimal.valueOf(ROUND_CEILING, 3), new BigDecimal("3.142")},
|
||||
{a_minus, b, BigDecimal.valueOf(ROUND_CEILING, 3), new BigDecimal("-3.141")},
|
||||
|
||||
{a, b, BigDecimal.valueOf(ROUND_FLOOR, 3), new BigDecimal("3.141")},
|
||||
{a_minus, b, BigDecimal.valueOf(ROUND_FLOOR, 3), new BigDecimal("-3.142")},
|
||||
|
||||
{a, b, BigDecimal.valueOf(ROUND_HALF_UP, 3), new BigDecimal("3.142")},
|
||||
{a_minus, b, BigDecimal.valueOf(ROUND_HALF_UP, 3), new BigDecimal("-3.142")},
|
||||
|
||||
{a, b, BigDecimal.valueOf(ROUND_DOWN, 3), new BigDecimal("3.141")},
|
||||
{a_minus, b, BigDecimal.valueOf(ROUND_DOWN, 3), new BigDecimal("-3.141")},
|
||||
|
||||
{a, b, BigDecimal.valueOf(ROUND_HALF_EVEN, 3), new BigDecimal("3.142")},
|
||||
{a_minus, b, BigDecimal.valueOf(ROUND_HALF_EVEN, 3), new BigDecimal("-3.142")},
|
||||
|
||||
{c, b, BigDecimal.valueOf(ROUND_HALF_EVEN, 3), new BigDecimal("3.142")},
|
||||
{c_minus, b, BigDecimal.valueOf(ROUND_HALF_EVEN, 3), new BigDecimal("-3.142")},
|
||||
|
||||
{d, e, BigDecimal.valueOf(ROUND_HALF_UP, -5), BigDecimal.valueOf(-1, -5)},
|
||||
{d, e, BigDecimal.valueOf(ROUND_HALF_DOWN, -5), BigDecimal.valueOf(0, -5)},
|
||||
{d, e, BigDecimal.valueOf(ROUND_HALF_EVEN, -5), BigDecimal.valueOf(0, -5)},
|
||||
};
|
||||
|
||||
for(BigDecimal tc[] : testCases) {
|
||||
int scale = tc[2].scale();
|
||||
int rm = tc[2].unscaledValue().intValue();
|
||||
|
||||
BigDecimal quotient = tc[0].divide(tc[1], scale, rm);
|
||||
if (!quotient.equals(tc[3])) {
|
||||
failures++;
|
||||
System.err.println("Unexpected quotient from " + tc[0] + " / " + tc[1] +
|
||||
" scale " + scale + " rounding mode " + RoundingMode.valueOf(rm) +
|
||||
"; expected " + tc[3] + " got " + quotient);
|
||||
}
|
||||
}
|
||||
|
||||
// 6876282
|
||||
BigDecimal[][] testCases2 = {
|
||||
// { dividend, divisor, expected quotient }
|
||||
{ new BigDecimal(3090), new BigDecimal(7), new BigDecimal(441) },
|
||||
{ new BigDecimal("309000000000000000000000"), new BigDecimal("700000000000000000000"),
|
||||
new BigDecimal(441) },
|
||||
{ new BigDecimal("962.430000000000"), new BigDecimal("8346463.460000000000"),
|
||||
new BigDecimal("0.000115309916") },
|
||||
{ new BigDecimal("18446744073709551631"), new BigDecimal("4611686018427387909"),
|
||||
new BigDecimal(4) },
|
||||
{ new BigDecimal("18446744073709551630"), new BigDecimal("4611686018427387909"),
|
||||
new BigDecimal(4) },
|
||||
{ new BigDecimal("23058430092136939523"), new BigDecimal("4611686018427387905"),
|
||||
new BigDecimal(5) },
|
||||
{ new BigDecimal("-18446744073709551661"), new BigDecimal("-4611686018427387919"),
|
||||
new BigDecimal(4) },
|
||||
{ new BigDecimal("-18446744073709551660"), new BigDecimal("-4611686018427387919"),
|
||||
new BigDecimal(4) },
|
||||
};
|
||||
|
||||
for (BigDecimal test[] : testCases2) {
|
||||
BigDecimal quo = test[0].divide(test[1], RoundingMode.HALF_UP);
|
||||
if (!quo.equals(test[2])) {
|
||||
failures++;
|
||||
System.err.println("Unexpected quotient from " + test[0] + " / " + test[1] +
|
||||
" rounding mode HALF_UP" +
|
||||
"; expected " + test[2] + " got " + quo);
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int divideByOneTests() {
|
||||
int failures = 0;
|
||||
|
||||
//problematic divisor: one with scale 17
|
||||
BigDecimal one = BigDecimal.ONE.setScale(17);
|
||||
RoundingMode rounding = RoundingMode.UNNECESSARY;
|
||||
|
||||
long[][] unscaledAndScale = new long[][] {
|
||||
{ Long.MAX_VALUE, 17},
|
||||
{-Long.MAX_VALUE, 17},
|
||||
{ Long.MAX_VALUE, 0},
|
||||
{-Long.MAX_VALUE, 0},
|
||||
{ Long.MAX_VALUE, 100},
|
||||
{-Long.MAX_VALUE, 100}
|
||||
};
|
||||
|
||||
for (long[] uas : unscaledAndScale) {
|
||||
long unscaled = uas[0];
|
||||
int scale = (int)uas[1];
|
||||
|
||||
BigDecimal noRound = null;
|
||||
try {
|
||||
noRound = BigDecimal.valueOf(unscaled, scale).
|
||||
divide(one, RoundingMode.UNNECESSARY);
|
||||
} catch (ArithmeticException e) {
|
||||
failures++;
|
||||
System.err.println("ArithmeticException for value " + unscaled
|
||||
+ " and scale " + scale + " without rounding");
|
||||
}
|
||||
|
||||
BigDecimal roundDown = null;
|
||||
try {
|
||||
roundDown = BigDecimal.valueOf(unscaled, scale).
|
||||
divide(one, RoundingMode.DOWN);
|
||||
} catch (ArithmeticException e) {
|
||||
failures++;
|
||||
System.err.println("ArithmeticException for value " + unscaled
|
||||
+ " and scale " + scale + " with rounding down");
|
||||
}
|
||||
|
||||
if (noRound != null && roundDown != null
|
||||
&& noRound.compareTo(roundDown) != 0) {
|
||||
failures++;
|
||||
System.err.println("Equality failure for value " + unscaled
|
||||
+ " and scale " + scale);
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += powersOf2and5();
|
||||
failures += nonTerminating();
|
||||
failures += properScaleTests();
|
||||
failures += trailingZeroTests();
|
||||
failures += scaledRoundedDivideTests();
|
||||
failures += divideByOneTests();
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing division.");
|
||||
}
|
||||
}
|
||||
}
|
||||
366
test/jdk/java/math/BigDecimal/DoubleFloatValueTests.java
Normal file
366
test/jdk/java/math/BigDecimal/DoubleFloatValueTests.java
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8205592 8339252 8341260
|
||||
* @summary Verify {double, float, float16}Value methods work
|
||||
* @modules jdk.incubator.vector
|
||||
* @library /test/lib
|
||||
* @key randomness
|
||||
* @build jdk.test.lib.RandomFactory
|
||||
* @run main DoubleFloatValueTests
|
||||
*/
|
||||
|
||||
import jdk.test.lib.RandomFactory;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Random;
|
||||
import jdk.incubator.vector.Float16;
|
||||
|
||||
public class DoubleFloatValueTests {
|
||||
private static final BigDecimal HALF = BigDecimal.valueOf(5, 1);
|
||||
private static final BigDecimal EPS = BigDecimal.valueOf(1, 10_000);
|
||||
|
||||
private static BigDecimal nextHalfUp(double v) {
|
||||
BigDecimal bv = new BigDecimal(v);
|
||||
BigDecimal ulp = new BigDecimal(Math.ulp(v));
|
||||
return bv.add(ulp.multiply(HALF));
|
||||
}
|
||||
|
||||
private static BigDecimal nextHalfDown(double v) {
|
||||
BigDecimal bv = new BigDecimal(v);
|
||||
BigDecimal ulp = new BigDecimal(v - Math.nextDown(v));
|
||||
return bv.subtract(ulp.multiply(HALF));
|
||||
}
|
||||
|
||||
private static BigDecimal nextHalfUp(float v) {
|
||||
BigDecimal bv = new BigDecimal(v);
|
||||
BigDecimal ulp = new BigDecimal(Math.ulp(v));
|
||||
return bv.add(ulp.multiply(HALF));
|
||||
}
|
||||
|
||||
private static BigDecimal nextHalfDown(float v) {
|
||||
BigDecimal bv = new BigDecimal(v);
|
||||
BigDecimal ulp = new BigDecimal(v - Math.nextDown(v));
|
||||
return bv.subtract(ulp.multiply(HALF));
|
||||
}
|
||||
|
||||
private static BigDecimal nextHalfUp(Float16 v) {
|
||||
BigDecimal bv = new BigDecimal(v.doubleValue());
|
||||
BigDecimal ulp = new BigDecimal(Float16.ulp(v).doubleValue());
|
||||
return bv.add(ulp.multiply(HALF));
|
||||
}
|
||||
|
||||
private static BigDecimal nextHalfDown(Float16 v) {
|
||||
BigDecimal bv = new BigDecimal(v.doubleValue());
|
||||
BigDecimal ulp = new BigDecimal(v.doubleValue() - Float16.nextDown(v).doubleValue());
|
||||
return bv.subtract(ulp.multiply(HALF));
|
||||
}
|
||||
|
||||
private static String toDecHexString(double v) {
|
||||
return v + " (" + Double.toHexString(v) + ")";
|
||||
}
|
||||
|
||||
private static String toDecHexString(float v) {
|
||||
return v + " (" + Float.toHexString(v) + ")";
|
||||
}
|
||||
|
||||
private static String toDecHexString(Float16 v) {
|
||||
return v + " (" + Float16.toHexString(v) + ")";
|
||||
}
|
||||
|
||||
private static void checkDouble(BigDecimal bd, double exp) {
|
||||
double res = bd.doubleValue();
|
||||
if (exp != res ) {
|
||||
String message = "Bad conversion: got " + toDecHexString(res) +
|
||||
", expected " + toDecHexString(exp);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkFloat(BigDecimal bv, float exp) {
|
||||
float res = bv.floatValue();
|
||||
if (exp != res ) {
|
||||
String message = "Bad conversion: got " + toDecHexString(res) +
|
||||
", expected " + toDecHexString(exp);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkFloat16(BigDecimal bv, Float16 exp) {
|
||||
Float16 res = Float16.valueOf(bv); // bv.float16Value();
|
||||
if (exp.floatValue() != res.floatValue()) {
|
||||
String message = "Bad conversion: got " + toDecHexString(res) +
|
||||
", expected " + toDecHexString(exp);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOdd(int n) {
|
||||
return (n & 0x1) != 0;
|
||||
}
|
||||
|
||||
private static void testDoubleValueNearMinValue() {
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal b = nextHalfUp(n * Double.MIN_VALUE);
|
||||
checkDouble(b, ((n + 1) / 2 * 2) * Double.MIN_VALUE);
|
||||
checkDouble(b.subtract(EPS), n * Double.MIN_VALUE);
|
||||
checkDouble(b.add(EPS), (n + 1) * Double.MIN_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testFloatValueNearMinValue() {
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal b = nextHalfUp(n * Float.MIN_VALUE);
|
||||
checkFloat(b, ((n + 1) / 2 * 2) * Float.MIN_VALUE);
|
||||
checkFloat(b.subtract(EPS), n * Float.MIN_VALUE);
|
||||
checkFloat(b.add(EPS), (n + 1) * Float.MIN_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testFloat16ValueNearMinValue() {
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal b = nextHalfUp(Float16.multiply(Float16.valueOf(n), Float16.MIN_VALUE));
|
||||
checkFloat16(b, Float16.multiply(Float16.valueOf((n + 1) / 2 * 2), Float16.MIN_VALUE));
|
||||
checkFloat16(b.subtract(EPS), Float16.multiply(Float16.valueOf(n), Float16.MIN_VALUE));
|
||||
checkFloat16(b.add(EPS), Float16.multiply(Float16.valueOf(n + 1), Float16.MIN_VALUE));
|
||||
}
|
||||
}
|
||||
|
||||
private static void testDoubleValueNearMinNormal() {
|
||||
double v = Double.MIN_NORMAL;
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal bv = nextHalfDown(v);
|
||||
checkDouble(bv, isOdd(n) ? Math.nextDown(v) : v);
|
||||
checkDouble(bv.subtract(EPS), Math.nextDown(v));
|
||||
checkDouble(bv.add(EPS), v);
|
||||
v = Math.nextDown(v);
|
||||
}
|
||||
v = Double.MIN_NORMAL;
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal bv = nextHalfUp(v);
|
||||
checkDouble(bv, isOdd(n) ? Math.nextUp(v) : v);
|
||||
checkDouble(bv.subtract(EPS), v);
|
||||
checkDouble(bv.add(EPS), Math.nextUp(v));
|
||||
v = Math.nextUp(v);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testFloatValueNearMinNormal() {
|
||||
float v = Float.MIN_NORMAL;
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal bv = nextHalfDown(v);
|
||||
checkFloat(bv, isOdd(n) ? Math.nextDown(v) : v);
|
||||
checkFloat(bv.subtract(EPS), Math.nextDown(v));
|
||||
checkFloat(bv.add(EPS), v);
|
||||
v = Math.nextDown(v);
|
||||
}
|
||||
v = Float.MIN_NORMAL;
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal bv = nextHalfUp(v);
|
||||
checkFloat(bv, isOdd(n) ? Math.nextUp(v) : v);
|
||||
checkFloat(bv.subtract(EPS), v);
|
||||
checkFloat(bv.add(EPS), Math.nextUp(v));
|
||||
v = Math.nextUp(v);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testFloat16ValueNearMinNormal() {
|
||||
Float16 v = Float16.MIN_NORMAL;
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal bv = nextHalfDown(v);
|
||||
checkFloat16(bv, isOdd(n) ? Float16.nextDown(v) : v);
|
||||
checkFloat16(bv.subtract(EPS), Float16.nextDown(v));
|
||||
checkFloat16(bv.add(EPS), v);
|
||||
v = Float16.nextDown(v);
|
||||
}
|
||||
v = Float16.MIN_NORMAL;
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal bv = nextHalfUp(v);
|
||||
checkFloat16(bv, isOdd(n) ? Float16.nextUp(v) : v);
|
||||
checkFloat16(bv.subtract(EPS), v);
|
||||
checkFloat16(bv.add(EPS), Float16.nextUp(v));
|
||||
v = Float16.nextUp(v);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testDoubleValueNearMaxValue() {
|
||||
double v = Double.MAX_VALUE;
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal bv = nextHalfDown(v);
|
||||
checkDouble(bv, isOdd(n) ? v : Math.nextDown(v));
|
||||
checkDouble(bv.subtract(EPS), Math.nextDown(v));
|
||||
checkDouble(bv.add(EPS), v);
|
||||
v = Math.nextDown(v);
|
||||
}
|
||||
BigDecimal bv = nextHalfUp(Double.MAX_VALUE);
|
||||
checkDouble(bv, Double.POSITIVE_INFINITY);
|
||||
checkDouble(bv.subtract(EPS), Double.MAX_VALUE);
|
||||
checkDouble(bv.add(EPS), Double.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
private static void testFloatValueNearMaxValue() {
|
||||
float v = Float.MAX_VALUE;
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal bv = nextHalfDown(v);
|
||||
checkFloat(bv, isOdd(n) ? v : Math.nextDown(v));
|
||||
checkFloat(bv.subtract(EPS), Math.nextDown(v));
|
||||
checkFloat(bv.add(EPS), v);
|
||||
v = Math.nextDown(v);
|
||||
}
|
||||
BigDecimal bv = nextHalfUp(Float.MAX_VALUE);
|
||||
checkFloat(bv, Float.POSITIVE_INFINITY);
|
||||
checkFloat(bv.subtract(EPS), Float.MAX_VALUE);
|
||||
checkFloat(bv.add(EPS), Float.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
private static void testFloat16ValueNearMaxValue() {
|
||||
Float16 v = Float16.MAX_VALUE;
|
||||
for (int n = 0; n < 100; ++n) {
|
||||
BigDecimal bv = nextHalfDown(v);
|
||||
checkFloat16(bv, isOdd(n) ? v : Float16.nextDown(v));
|
||||
checkFloat16(bv.subtract(EPS), Float16.nextDown(v));
|
||||
checkFloat16(bv.add(EPS), v);
|
||||
v = Float16.nextDown(v);
|
||||
}
|
||||
BigDecimal bv = nextHalfUp(Float16.MAX_VALUE);
|
||||
checkFloat16(bv, Float16.POSITIVE_INFINITY);
|
||||
checkFloat16(bv.subtract(EPS), Float16.MAX_VALUE);
|
||||
checkFloat16(bv.add(EPS), Float16.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
private static void testDoubleValueRandom() {
|
||||
Random r = RandomFactory.getRandom();
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
double v = r.nextDouble(-Double.MAX_VALUE, Double.MAX_VALUE);
|
||||
checkDouble(new BigDecimal(v), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
double v = r.nextDouble(-1e9, 1e9);
|
||||
checkDouble(new BigDecimal(v), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
double v = r.nextDouble(-1e6, 1e6);
|
||||
checkDouble(new BigDecimal(v), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
double v = r.nextDouble(-1e-6, 1e-6);
|
||||
checkDouble(new BigDecimal(v), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
double v = r.nextDouble(-1e-9, 1e-9);
|
||||
checkDouble(new BigDecimal(v), v);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testFloatValueRandom() {
|
||||
Random r = RandomFactory.getRandom();
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
float v = r.nextFloat(-Float.MAX_VALUE, Float.MAX_VALUE);
|
||||
checkFloat(new BigDecimal(v), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
float v = r.nextFloat(-1e9f, 1e9f);
|
||||
checkFloat(new BigDecimal(v), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
float v = r.nextFloat(-1e6f, 1e6f);
|
||||
checkFloat(new BigDecimal(v), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
float v = r.nextFloat(-1e-6f, 1e-6f);
|
||||
checkFloat(new BigDecimal(v), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
float v = r.nextFloat(-1e-9f, 1e-9f);
|
||||
checkFloat(new BigDecimal(v), v);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testFloat16ValueRandom() {
|
||||
Random r = RandomFactory.getRandom();
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
Float16 v = Float16.valueOf(r.nextFloat(-Float16.MAX_VALUE.floatValue(), Float16.MAX_VALUE.floatValue()));
|
||||
checkFloat16(new BigDecimal(v.floatValue()), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
Float16 v = Float16.valueOf(r.nextFloat(-1e4f, 1e4f));
|
||||
checkFloat16(new BigDecimal(v.floatValue()), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
Float16 v = Float16.valueOf(r.nextFloat(-1e3f, 1e3f));
|
||||
checkFloat16(new BigDecimal(v.floatValue()), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
Float16 v = Float16.valueOf(r.nextFloat(-1e-3f, 1e-3f));
|
||||
checkFloat16(new BigDecimal(v.floatValue()), v);
|
||||
}
|
||||
for (int i = 0; i < 10_000; ++i) {
|
||||
Float16 v = Float16.valueOf(r.nextFloat(-1e-4f, 1e-4f));
|
||||
checkFloat16(new BigDecimal(v.floatValue()), v);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testDoubleValueExtremes() {
|
||||
checkDouble(BigDecimal.valueOf(1, 1000), 0.0);
|
||||
checkDouble(BigDecimal.valueOf(-1, 1000), -0.0);
|
||||
checkDouble(BigDecimal.valueOf(1, -1000), Double.POSITIVE_INFINITY);
|
||||
checkDouble(BigDecimal.valueOf(-1, -1000), Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
private static void testFloatValueExtremes() {
|
||||
checkFloat(BigDecimal.valueOf(1, 1000), 0.0f);
|
||||
checkFloat(BigDecimal.valueOf(-1, 1000), -0.0f);
|
||||
checkFloat(BigDecimal.valueOf(1, -1000), Float.POSITIVE_INFINITY);
|
||||
checkFloat(BigDecimal.valueOf(-1, -1000), Float.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
private static void testFloat16ValueExtremes() {
|
||||
checkFloat16(BigDecimal.valueOf(1, 1000), Float16.valueOf(0.0f));
|
||||
checkFloat16(BigDecimal.valueOf(-1, 1000), Float16.valueOf(-0.0f));
|
||||
checkFloat16(BigDecimal.valueOf(1, -1000), Float16.POSITIVE_INFINITY);
|
||||
checkFloat16(BigDecimal.valueOf(-1, -1000), Float16.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
testDoubleValueNearMinValue();
|
||||
testDoubleValueNearMinNormal();
|
||||
testDoubleValueNearMaxValue();
|
||||
testDoubleValueRandom();
|
||||
testDoubleValueExtremes();
|
||||
|
||||
testFloatValueNearMinValue();
|
||||
testFloatValueNearMinNormal();
|
||||
testFloatValueNearMaxValue();
|
||||
testFloatValueRandom();
|
||||
testFloatValueExtremes();
|
||||
|
||||
testFloat16ValueNearMinValue();
|
||||
testFloat16ValueNearMinNormal();
|
||||
testFloat16ValueNearMaxValue();
|
||||
testFloat16ValueRandom();
|
||||
testFloat16ValueExtremes();
|
||||
}
|
||||
|
||||
}
|
||||
91
test/jdk/java/math/BigDecimal/EqualsTests.java
Normal file
91
test/jdk/java/math/BigDecimal/EqualsTests.java
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 1234567
|
||||
* @summary Test BigDecimal.equals() method.
|
||||
* @author xlu
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import static java.math.BigDecimal.*;
|
||||
|
||||
public class EqualsTests {
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal[][] testValues = {
|
||||
// The even index is supposed to return true for equals call and
|
||||
// the odd index is supposed to return false, i.e. not equal.
|
||||
{ZERO, ZERO},
|
||||
{ONE, TEN},
|
||||
|
||||
{valueOf(Integer.MAX_VALUE), valueOf(Integer.MAX_VALUE)},
|
||||
{valueOf(Long.MAX_VALUE), valueOf(-Long.MAX_VALUE)},
|
||||
|
||||
{valueOf(12345678), valueOf(12345678)},
|
||||
{valueOf(123456789), valueOf(123456788)},
|
||||
|
||||
{new BigDecimal("123456789123456789123"),
|
||||
new BigDecimal(new BigInteger("123456789123456789123"))},
|
||||
{new BigDecimal("123456789123456789123"),
|
||||
new BigDecimal(new BigInteger("123456789123456789124"))},
|
||||
|
||||
{valueOf(Long.MIN_VALUE), new BigDecimal("-9223372036854775808")},
|
||||
{new BigDecimal("9223372036854775808"), valueOf(Long.MAX_VALUE)},
|
||||
|
||||
{valueOf(Math.round(Math.pow(2, 10))), new BigDecimal("1024")},
|
||||
{new BigDecimal("1020"), valueOf(Math.pow(2, 11))},
|
||||
|
||||
{new BigDecimal(BigInteger.valueOf(2).pow(65)),
|
||||
new BigDecimal("36893488147419103232")},
|
||||
{new BigDecimal("36893488147419103231.81"),
|
||||
new BigDecimal("36893488147419103231.811"),
|
||||
}
|
||||
};
|
||||
|
||||
boolean expected = Boolean.TRUE;
|
||||
for (BigDecimal[] testValuePair : testValues) {
|
||||
failures += equalsTest(testValuePair[0], testValuePair[1], expected);
|
||||
expected = !expected;
|
||||
}
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Inccured " + failures +
|
||||
" failures while testing equals.");
|
||||
}
|
||||
}
|
||||
|
||||
private static int equalsTest(BigDecimal l, BigDecimal r, boolean expected) {
|
||||
boolean result = l.equals(r);
|
||||
int failed = (result == expected) ? 0 : 1;
|
||||
|
||||
if (failed == 1) {
|
||||
System.err.println(l + " .equals(" + r + ") => " + result +
|
||||
"\n\tExpected " + expected);
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
}
|
||||
188
test/jdk/java/math/BigDecimal/FloatDoubleValueTests.java
Normal file
188
test/jdk/java/math/BigDecimal/FloatDoubleValueTests.java
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6274390 7082971
|
||||
* @summary Verify {float, double}Value methods work with condensed representation
|
||||
* @run main FloatDoubleValueTests
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox -XX:AutoBoxCacheMax=20000 FloatDoubleValueTests
|
||||
*/
|
||||
import java.math.*;
|
||||
|
||||
public class FloatDoubleValueTests {
|
||||
private static final long two2the24 = 1L<<23;
|
||||
private static final long two2the53 = 1L<<52;
|
||||
|
||||
// Largest long that fits exactly in a float
|
||||
private static final long maxFltLong = (long)(Integer.MAX_VALUE & ~(0xff));
|
||||
|
||||
// Largest long that fits exactly in a double
|
||||
private static final long maxDblLong = Long.MAX_VALUE & ~(0x7ffL);
|
||||
|
||||
static void testDoubleValue0(long i, BigDecimal bd) {
|
||||
if (bd.doubleValue() != i ||
|
||||
bd.longValue() != i)
|
||||
throw new RuntimeException("Unexpected equality failure for " +
|
||||
i + "\t" + bd);
|
||||
}
|
||||
|
||||
static void testFloatValue0(long i, BigDecimal bd) {
|
||||
if (bd.floatValue() != i ||
|
||||
bd.longValue() != i)
|
||||
throw new RuntimeException("Unexpected equality failure for " +
|
||||
i + "\t" + bd);
|
||||
}
|
||||
|
||||
static void checkFloat(BigDecimal bd, float f) {
|
||||
float fbd = bd.floatValue();
|
||||
if (f != fbd ) {
|
||||
String message = String.format("Bad conversion:"+
|
||||
"got %g (%a)\texpected %g (%a)",
|
||||
f, f, fbd, fbd);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
static void checkDouble(BigDecimal bd, double d) {
|
||||
double dbd = bd.doubleValue();
|
||||
|
||||
if (d != dbd ) {
|
||||
String message = String.format("Bad conversion:"+
|
||||
"got %g (%a)\texpected %g (%a)",
|
||||
d, d, dbd, dbd);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
// Test integral values that will convert exactly to both float
|
||||
// and double.
|
||||
static void testFloatDoubleValue() {
|
||||
long longValues[] = {
|
||||
Long.MIN_VALUE, // -2^63
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
|
||||
two2the24-1,
|
||||
two2the24,
|
||||
two2the24+1,
|
||||
|
||||
maxFltLong-1,
|
||||
maxFltLong,
|
||||
maxFltLong+1,
|
||||
};
|
||||
|
||||
for(long i : longValues) {
|
||||
BigDecimal bd1 = new BigDecimal(i);
|
||||
BigDecimal bd2 = new BigDecimal(-i);
|
||||
|
||||
testDoubleValue0( i, bd1);
|
||||
testDoubleValue0(-i, bd2);
|
||||
|
||||
testFloatValue0( i, bd1);
|
||||
testFloatValue0(-i, bd2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void testDoubleValue() {
|
||||
long longValues[] = {
|
||||
Integer.MAX_VALUE-1,
|
||||
Integer.MAX_VALUE,
|
||||
(long)Integer.MAX_VALUE+1,
|
||||
|
||||
two2the53-1,
|
||||
two2the53,
|
||||
two2the53+1,
|
||||
|
||||
maxDblLong,
|
||||
};
|
||||
|
||||
// Test integral values that will convert exactly to double
|
||||
// but not float.
|
||||
for(long i : longValues) {
|
||||
BigDecimal bd1 = new BigDecimal(i);
|
||||
BigDecimal bd2 = new BigDecimal(-i);
|
||||
|
||||
testDoubleValue0( i, bd1);
|
||||
testDoubleValue0(-i, bd2);
|
||||
|
||||
checkFloat(bd1, (float)i);
|
||||
checkFloat(bd2, -(float)i);
|
||||
}
|
||||
|
||||
// Now check values that should not convert the same in double
|
||||
for(long i = maxDblLong; i < Long.MAX_VALUE; i++) {
|
||||
BigDecimal bd1 = new BigDecimal(i);
|
||||
BigDecimal bd2 = new BigDecimal(-i);
|
||||
checkDouble(bd1, (double)i);
|
||||
checkDouble(bd2, -(double)i);
|
||||
|
||||
checkFloat(bd1, (float)i);
|
||||
checkFloat(bd2, -(float)i);
|
||||
}
|
||||
|
||||
checkDouble(new BigDecimal(Long.MIN_VALUE), (double)Long.MIN_VALUE);
|
||||
checkDouble(new BigDecimal(Long.MAX_VALUE), (double)Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
static void testFloatValue() {
|
||||
// Now check values that should not convert the same in float
|
||||
for(long i = maxFltLong; i <= Integer.MAX_VALUE; i++) {
|
||||
BigDecimal bd1 = new BigDecimal(i);
|
||||
BigDecimal bd2 = new BigDecimal(-i);
|
||||
checkFloat(bd1, (float)i);
|
||||
checkFloat(bd2, -(float)i);
|
||||
|
||||
testDoubleValue0( i, bd1);
|
||||
testDoubleValue0(-i, bd2);
|
||||
}
|
||||
}
|
||||
|
||||
static void testFloatValue1() {
|
||||
checkFloat(new BigDecimal("85070591730234615847396907784232501249"), 8.507059e+37f);
|
||||
checkFloat(new BigDecimal("7784232501249e12"), 7.7842326e24f);
|
||||
checkFloat(new BigDecimal("907784232501249e-12"),907.78424f);
|
||||
checkFloat(new BigDecimal("7784e8"),7.7839997e11f);
|
||||
checkFloat(new BigDecimal("9077e-8"),9.077e-5f);
|
||||
|
||||
}
|
||||
|
||||
static void testDoubleValue1() {
|
||||
checkDouble(new BigDecimal("85070591730234615847396907784232501249"), 8.507059173023462e37);
|
||||
checkDouble(new BigDecimal("7784232501249e12"), 7.784232501249e24);
|
||||
checkDouble(new BigDecimal("907784232501249e-12"), 907.784232501249);
|
||||
checkDouble(new BigDecimal("7784e8"), 7.784e11);
|
||||
checkDouble(new BigDecimal("9077e-8"), 9.077e-5);
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
testFloatDoubleValue();
|
||||
testDoubleValue();
|
||||
testFloatValue();
|
||||
testFloatValue1();
|
||||
testDoubleValue1();
|
||||
}
|
||||
}
|
||||
120
test/jdk/java/math/BigDecimal/IntValueExactTests.java
Normal file
120
test/jdk/java/math/BigDecimal/IntValueExactTests.java
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8211936
|
||||
* @summary Tests of BigDecimal.intValueExact
|
||||
*/
|
||||
import java.math.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import static java.util.Map.entry;
|
||||
|
||||
public class IntValueExactTests {
|
||||
public static void main(String... args) {
|
||||
int failures = 0;
|
||||
|
||||
failures += intValueExactSuccessful();
|
||||
failures += intValueExactExceptional();
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing intValueExact.");
|
||||
}
|
||||
}
|
||||
|
||||
private static int simpleIntValueExact(BigDecimal bd) {
|
||||
return bd.toBigIntegerExact().intValue();
|
||||
}
|
||||
|
||||
private static int intValueExactSuccessful() {
|
||||
int failures = 0;
|
||||
|
||||
// Strings used to create BigDecimal instances on which invoking
|
||||
// intValueExact() will succeed.
|
||||
Map<BigDecimal, Integer> successCases =
|
||||
Map.ofEntries(entry(new BigDecimal("2147483647"), Integer.MAX_VALUE), // 2^31 -1
|
||||
entry(new BigDecimal("2147483647.0"), Integer.MAX_VALUE),
|
||||
entry(new BigDecimal("2147483647.00"), Integer.MAX_VALUE),
|
||||
|
||||
entry(new BigDecimal("-2147483648"), Integer.MIN_VALUE), // -2^31
|
||||
entry(new BigDecimal("-2147483648.0"), Integer.MIN_VALUE),
|
||||
entry(new BigDecimal("-2147483648.00"),Integer.MIN_VALUE),
|
||||
|
||||
entry(new BigDecimal("1e0"), 1),
|
||||
entry(new BigDecimal(BigInteger.ONE, -9), 1_000_000_000),
|
||||
|
||||
entry(new BigDecimal("0e13"), 0), // Fast path zero
|
||||
entry(new BigDecimal("0e32"), 0),
|
||||
entry(new BigDecimal("0e512"), 0),
|
||||
|
||||
entry(new BigDecimal("10.000000000000000000000000000000000"), 10));
|
||||
|
||||
for (var testCase : successCases.entrySet()) {
|
||||
BigDecimal bd = testCase.getKey();
|
||||
int expected = testCase.getValue();
|
||||
try {
|
||||
int intValueExact = bd.intValueExact();
|
||||
if (expected != intValueExact ||
|
||||
intValueExact != simpleIntValueExact(bd)) {
|
||||
failures++;
|
||||
System.err.println("Unexpected intValueExact result " + intValueExact +
|
||||
" on " + bd);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failures++;
|
||||
System.err.println("Error on " + bd + "\tException message:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int intValueExactExceptional() {
|
||||
int failures = 0;
|
||||
List<BigDecimal> exceptionalCases =
|
||||
List.of(new BigDecimal("2147483648"), // Integer.MAX_VALUE + 1
|
||||
new BigDecimal("2147483648.0"),
|
||||
new BigDecimal("2147483648.00"),
|
||||
new BigDecimal("-2147483649"), // Integer.MIN_VALUE - 1
|
||||
new BigDecimal("-2147483649.1"),
|
||||
new BigDecimal("-2147483649.01"),
|
||||
|
||||
new BigDecimal("9999999999999999999999999999999"),
|
||||
new BigDecimal("10000000000000000000000000000000"),
|
||||
|
||||
new BigDecimal("0.99"),
|
||||
new BigDecimal("0.999999999999999999999"));
|
||||
|
||||
for (BigDecimal bd : exceptionalCases) {
|
||||
try {
|
||||
int intValueExact = bd.intValueExact();
|
||||
failures++;
|
||||
System.err.println("Unexpected non-exceptional intValueExact on " + bd);
|
||||
} catch (ArithmeticException e) {
|
||||
// Success;
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
}
|
||||
352
test/jdk/java/math/BigDecimal/IntegralDivisionTests.java
Normal file
352
test/jdk/java/math/BigDecimal/IntegralDivisionTests.java
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 4904082 4917089 6337226 6378503
|
||||
* @summary Tests that integral division and related methods return the proper result and scale.
|
||||
*/
|
||||
import java.math.*;
|
||||
public class IntegralDivisionTests {
|
||||
|
||||
static int dividetoIntegralValueTests() {
|
||||
int failures = 0;
|
||||
|
||||
// Exact integer quotient should have the same results from
|
||||
// the exact divide and dividetoIntegralValue
|
||||
|
||||
|
||||
// Rounded results
|
||||
BigDecimal [][] moreTestCases = {
|
||||
{new BigDecimal("11003"), new BigDecimal("10"), new BigDecimal("1100")},
|
||||
{new BigDecimal("11003"), new BigDecimal("1e1"), new BigDecimal("1100.0")},
|
||||
{new BigDecimal("1e9"), new BigDecimal("1"), new BigDecimal("1e9")},
|
||||
{new BigDecimal("1e9"), new BigDecimal("1.00"), new BigDecimal("1e9")},
|
||||
{new BigDecimal("1e9"), new BigDecimal("0.1"), new BigDecimal("1e10")},
|
||||
{new BigDecimal("10e8"), new BigDecimal("0.1"), new BigDecimal("10e9")},
|
||||
{new BigDecimal("400e1"), new BigDecimal("5"), new BigDecimal("80e1")},
|
||||
{new BigDecimal("400e1"), new BigDecimal("4.999999999"), new BigDecimal("8e2")},
|
||||
{new BigDecimal("40e2"), new BigDecimal("5"), new BigDecimal("8e2")},
|
||||
{BigDecimal.valueOf(1, Integer.MIN_VALUE),
|
||||
BigDecimal.valueOf(1, -(Integer.MAX_VALUE & 0x7fffff00)),
|
||||
BigDecimal.valueOf(1, -256)},
|
||||
};
|
||||
|
||||
for(BigDecimal [] testCase: moreTestCases) {
|
||||
BigDecimal quotient;
|
||||
if (! (quotient=testCase[0].divideToIntegralValue(testCase[1])).equals(testCase[2]) ){
|
||||
failures++;
|
||||
// BigDecimal exact = testCase[0].divide(testCase[1]);
|
||||
System.err.println();
|
||||
System.err.println("dividend = " + testCase[0] + " scale = " + testCase[0].scale());
|
||||
System.err.println("divisor = " + testCase[1] + " scale = " + testCase[1].scale());
|
||||
System.err.println("quotient = " + quotient + " scale = " + quotient.scale());
|
||||
System.err.println("expected = " + testCase[2] + " scale = " + testCase[2].scale());
|
||||
// System.err.println("exact = " + exact + " scale = " + exact.scale());
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int dividetoIntegralValueRoundedTests() {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal dividend = new BigDecimal("11003");
|
||||
BigDecimal divisor = new BigDecimal("10");
|
||||
BigDecimal [] quotients = { // Expected results with precision =
|
||||
new BigDecimal("1100"), // 0
|
||||
null, // 1
|
||||
new BigDecimal("11e2"), // 2
|
||||
new BigDecimal("110e1"), // 3
|
||||
new BigDecimal("1100"), // 4
|
||||
};
|
||||
failures += divideContextTestPrecs(dividend, divisor, quotients);
|
||||
|
||||
dividend = new BigDecimal("11003");
|
||||
divisor = new BigDecimal("1e1");
|
||||
BigDecimal [] quotients2 = { // Expected results with precision =
|
||||
new BigDecimal("1100.0"), // 0
|
||||
null, // 1
|
||||
new BigDecimal("11e2"), // 2
|
||||
new BigDecimal("110e1"), // 3
|
||||
new BigDecimal("1100"), // 4
|
||||
new BigDecimal("1100.0"), // 5
|
||||
};
|
||||
failures += divideContextTestPrecs(dividend, divisor, quotients2);
|
||||
|
||||
dividend = new BigDecimal("1230000");
|
||||
divisor = new BigDecimal("100");
|
||||
BigDecimal [] quotients3 = { // Expected results with precision =
|
||||
new BigDecimal("12300"), // 0
|
||||
null, // 1
|
||||
null, // 2
|
||||
new BigDecimal("123e2"), // 3
|
||||
new BigDecimal("1230e1"), // 4
|
||||
new BigDecimal("12300"), // 5
|
||||
};
|
||||
failures += divideContextTestPrecs(dividend, divisor, quotients3);
|
||||
|
||||
dividend = new BigDecimal("33");
|
||||
divisor = new BigDecimal("3");
|
||||
BigDecimal [] quotients4 = { // Expected results with precision =
|
||||
new BigDecimal("11"), // 0
|
||||
null, // 1
|
||||
new BigDecimal("11"), // 2
|
||||
new BigDecimal("11"), // 3
|
||||
};
|
||||
failures += divideContextTestPrecs(dividend, divisor, quotients4);
|
||||
|
||||
dividend = new BigDecimal("34");
|
||||
divisor = new BigDecimal("3");
|
||||
BigDecimal [] quotients5 = { // Expected results with precision =
|
||||
new BigDecimal("11"), // 0
|
||||
null, // 1
|
||||
new BigDecimal("11"), // 2
|
||||
new BigDecimal("11"), // 3
|
||||
};
|
||||
failures += divideContextTestPrecs(dividend, divisor, quotients5);
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int divideContextTestPrecs(BigDecimal dividend,
|
||||
BigDecimal divisor,
|
||||
BigDecimal[] quotients)
|
||||
{
|
||||
int failures = 0;
|
||||
for(int i = 0; i < quotients.length; i++) {
|
||||
BigDecimal result = null;
|
||||
BigDecimal quotient = quotients[i];
|
||||
|
||||
try {
|
||||
result = dividend.divideToIntegralValue(divisor,
|
||||
new MathContext(i, RoundingMode.DOWN));
|
||||
} catch (ArithmeticException e) {
|
||||
if (quotient != null) {
|
||||
failures++;
|
||||
System.err.println();
|
||||
System.err.println("Unexpected exception:");
|
||||
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
|
||||
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
|
||||
System.err.println("expected = " + quotient + " scale = " + quotient.scale());
|
||||
}
|
||||
}
|
||||
|
||||
if (quotient != null) {
|
||||
if (! result.equals(quotient)) {
|
||||
failures++;
|
||||
System.err.println();
|
||||
System.err.println("Unexpected result:");
|
||||
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
|
||||
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
|
||||
System.err.println("quotient = " + result + " scale = " + result.scale());
|
||||
System.err.println("expected = " + quotient + " scale = " + quotient.scale());
|
||||
System.err.println("precision = " + i);
|
||||
}
|
||||
} else {
|
||||
if (result != null) {
|
||||
failures++;
|
||||
System.err.println();
|
||||
System.err.println("Unexpected unexceptional result:");
|
||||
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
|
||||
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
|
||||
System.err.println("quotient = " + result + " scale = " + result.scale());
|
||||
System.err.println("precision = " + i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
|
||||
static int divideContextTests(BigDecimal dividend,
|
||||
BigDecimal divisor,
|
||||
BigDecimal expected,
|
||||
MathContext mc) {
|
||||
int failures = 0;
|
||||
|
||||
failures += divideContextTest(dividend, divisor, expected, mc);
|
||||
failures += divideContextTest(dividend.negate(), divisor.negate(), expected, mc);
|
||||
|
||||
if (expected != null) {
|
||||
failures += divideContextTest(dividend.negate(), divisor, expected.negate(), mc);
|
||||
failures += divideContextTest(dividend, divisor.negate(), expected.negate(), mc);
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
|
||||
static int divideContextTest(BigDecimal dividend,
|
||||
BigDecimal divisor,
|
||||
BigDecimal expected,
|
||||
MathContext mc)
|
||||
{
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal result = null;
|
||||
|
||||
try {
|
||||
result = dividend.divideToIntegralValue(divisor, mc);
|
||||
} catch (ArithmeticException e) {
|
||||
if (expected != null) {
|
||||
failures++;
|
||||
System.err.println();
|
||||
System.err.println("Unexpected exception:");
|
||||
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
|
||||
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
|
||||
System.err.println("expected = " + expected + " scale = " + expected.scale());
|
||||
System.err.println("MathContext = " + mc);
|
||||
}
|
||||
}
|
||||
|
||||
if (expected != null) {
|
||||
if (! result.equals(expected)) {
|
||||
failures++;
|
||||
System.err.println();
|
||||
System.err.println("Unexpected result:");
|
||||
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
|
||||
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
|
||||
System.err.println("expected = " + expected + " scale = " + expected.scale());
|
||||
System.err.println("result = " + result + " scale = " + result.scale());
|
||||
System.err.println("MathContext = " + mc);
|
||||
}
|
||||
} else {
|
||||
if (result != null) {
|
||||
failures++;
|
||||
System.err.println();
|
||||
System.err.println("Unexpected unexceptional result:");
|
||||
System.err.println("dividend = " + dividend + " scale = " + dividend.scale());
|
||||
System.err.println("divisor = " + divisor + " scale = " + divisor.scale());
|
||||
System.err.println("quotient = " + result + " scale = " + result.scale());
|
||||
System.err.println("MathConext = " + mc);
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int dividetoIntegralValueScalingTests() {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal dividend = new BigDecimal("123456789000");
|
||||
BigDecimal divisor = BigDecimal.ONE;
|
||||
BigDecimal expected = new BigDecimal("123456789e3");
|
||||
MathContext mc = new MathContext(9,RoundingMode.DOWN);
|
||||
failures += divideContextTests(dividend, divisor, expected, mc);
|
||||
|
||||
|
||||
// 100/3 = 33 remainder 1
|
||||
int [] precisions = {0, 2, 3, 4};
|
||||
dividend = new BigDecimal(100);
|
||||
divisor = new BigDecimal(3);
|
||||
expected = new BigDecimal(33);
|
||||
|
||||
for(RoundingMode rm: RoundingMode.values())
|
||||
for(int precision: precisions) {
|
||||
failures += divideContextTests(dividend, divisor, expected,
|
||||
new MathContext(precision, rm));
|
||||
}
|
||||
|
||||
// 123000/10 = 12300 remainder 0
|
||||
dividend = new BigDecimal(123000);
|
||||
divisor = new BigDecimal(10);
|
||||
int[] precisions1 = {0, 1, 2, 3, 4, 5};
|
||||
BigDecimal[] expected1 = {
|
||||
new BigDecimal("12300"),
|
||||
null,
|
||||
null,
|
||||
new BigDecimal("123e2"),
|
||||
new BigDecimal("1230e1"),
|
||||
new BigDecimal("12300"),
|
||||
};
|
||||
|
||||
for(RoundingMode rm: RoundingMode.values())
|
||||
for(int i = 0; i < precisions1.length; i++) {
|
||||
failures += divideContextTests(dividend, divisor,
|
||||
expected1[i],
|
||||
new MathContext(precisions1[i], rm));
|
||||
}
|
||||
|
||||
// 123e3/10 = 123e2 remainder 0
|
||||
dividend = new BigDecimal("123e3");
|
||||
divisor = new BigDecimal(10);
|
||||
int[] precisions2 = {0, 1, 2, 3, 4, 5};
|
||||
BigDecimal[] expected2 = {
|
||||
new BigDecimal("123e2"),
|
||||
null,
|
||||
null,
|
||||
new BigDecimal("123e2"),
|
||||
new BigDecimal("123e2"),
|
||||
new BigDecimal("123e2"),
|
||||
};
|
||||
|
||||
for(RoundingMode rm: RoundingMode.values())
|
||||
for(int i = 0; i < precisions2.length; i++) {
|
||||
failures += divideContextTests(dividend, divisor,
|
||||
expected2[i],
|
||||
new MathContext(precisions2[i], rm));
|
||||
}
|
||||
|
||||
|
||||
// 123000/1e1 = 12300.0 remainder 0
|
||||
dividend = new BigDecimal("123000");
|
||||
divisor = new BigDecimal("1e1");
|
||||
int[] precisions3 = {0, 1, 2, 3, 4, 5, 6};
|
||||
BigDecimal[] expected3 = {
|
||||
new BigDecimal("12300.0"),
|
||||
null,
|
||||
null,
|
||||
new BigDecimal("123e2"),
|
||||
new BigDecimal("1230e1"),
|
||||
new BigDecimal("12300"),
|
||||
new BigDecimal("12300.0"),
|
||||
};
|
||||
|
||||
for(RoundingMode rm: RoundingMode.values())
|
||||
for(int i = 0; i < precisions3.length; i++) {
|
||||
failures += divideContextTests(dividend, divisor,
|
||||
expected3[i],
|
||||
new MathContext(precisions3[i], rm));
|
||||
}
|
||||
|
||||
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += dividetoIntegralValueTests();
|
||||
failures += dividetoIntegralValueRoundedTests();
|
||||
failures += dividetoIntegralValueScalingTests();
|
||||
|
||||
if (failures > 0) {
|
||||
System.err.println("Encountered " + failures +
|
||||
" failures while testing integral division.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
241
test/jdk/java/math/BigDecimal/IntegralValueTests.java
Normal file
241
test/jdk/java/math/BigDecimal/IntegralValueTests.java
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8211936
|
||||
* @summary Tests of BigDecimal.intValue() and BigDecimal.longValue()
|
||||
*/
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
public class IntegralValueTests {
|
||||
public static void main(String... args) {
|
||||
int failures =
|
||||
integralValuesTest(INT_VALUES, true) +
|
||||
integralValuesTest(LONG_VALUES, false);
|
||||
if (failures != 0) {
|
||||
throw new RuntimeException
|
||||
("Incurred " + failures + " failures for {int,long}Value().");
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<BigDecimal, Number> INT_VALUES =
|
||||
Map.ofEntries(
|
||||
|
||||
// 2**31 - 1
|
||||
Map.entry(new BigDecimal("2147483647"), Integer.MAX_VALUE),
|
||||
Map.entry(new BigDecimal("2147483647.0"), Integer.MAX_VALUE),
|
||||
Map.entry(new BigDecimal("2147483647.00"), Integer.MAX_VALUE),
|
||||
|
||||
Map.entry(new BigDecimal("-2147483647"), -Integer.MAX_VALUE),
|
||||
Map.entry(new BigDecimal("-2147483647.0"), -Integer.MAX_VALUE),
|
||||
|
||||
// -2**31
|
||||
Map.entry(new BigDecimal("-2147483648"), Integer.MIN_VALUE),
|
||||
Map.entry(new BigDecimal("-2147483648.1"), Integer.MIN_VALUE),
|
||||
Map.entry(new BigDecimal("-2147483648.01"), Integer.MIN_VALUE),
|
||||
|
||||
// -2**31 + 1 truncation to 2**31 - 1
|
||||
Map.entry(new BigDecimal("-2147483649"), Integer.MAX_VALUE),
|
||||
|
||||
// 2**64 - 1 truncation to 1
|
||||
Map.entry(new BigDecimal("4294967295"), -1),
|
||||
|
||||
// 2**64 truncation to 0
|
||||
Map.entry(new BigDecimal("4294967296"), 0),
|
||||
|
||||
// Fast path truncation to 0
|
||||
Map.entry(new BigDecimal("1e32"), 0),
|
||||
|
||||
// Slow path truncation to -2**31
|
||||
Map.entry(new BigDecimal("1e31"), Integer.MIN_VALUE),
|
||||
|
||||
// Slow path
|
||||
Map.entry(new BigDecimal("1e0"), 1),
|
||||
|
||||
// Fast path round to 0
|
||||
Map.entry(new BigDecimal("9e-1"), 0),
|
||||
|
||||
// Some random values
|
||||
Map.entry(new BigDecimal("900e-1"), 90), // Increasing negative exponents
|
||||
Map.entry(new BigDecimal("900e-2"), 9),
|
||||
Map.entry(new BigDecimal("900e-3"), 0),
|
||||
|
||||
// Fast path round to 0
|
||||
Map.entry(new BigDecimal("123456789e-9"), 0),
|
||||
|
||||
// Slow path round to 1
|
||||
Map.entry(new BigDecimal("123456789e-8"), 1),
|
||||
|
||||
// Increasing positive exponents
|
||||
Map.entry(new BigDecimal("10000001e1"), 100000010),
|
||||
Map.entry(new BigDecimal("10000001e10"), -1315576832),
|
||||
Map.entry(new BigDecimal("10000001e100"), 0),
|
||||
Map.entry(new BigDecimal("10000001e1000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e10000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e100000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e1000000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e10000000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e100000000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e1000000000"), 0),
|
||||
|
||||
// Increasing negative exponents
|
||||
Map.entry(new BigDecimal("10000001e-1"), 1000000),
|
||||
Map.entry(new BigDecimal("10000001e-10"), 0),
|
||||
Map.entry(new BigDecimal("10000001e-100"), 0),
|
||||
Map.entry(new BigDecimal("10000001e-1000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e-10000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e-100000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e-1000000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e-10000000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e-100000000"), 0),
|
||||
Map.entry(new BigDecimal("10000001e-1000000000"), 0),
|
||||
|
||||
// Currency calculation to 4 places
|
||||
Map.entry(new BigDecimal("12345.0001"), 12345),
|
||||
Map.entry(new BigDecimal("12345.9999"), 12345),
|
||||
Map.entry(new BigDecimal("-12345.0001"), -12345),
|
||||
Map.entry(new BigDecimal("-12345.9999"), -12345));
|
||||
|
||||
private static final Map<BigDecimal, Number> LONG_VALUES =
|
||||
Map.ofEntries(
|
||||
// 2**63 - 1
|
||||
Map.entry(new BigDecimal("9223372036854775807"), Long.MAX_VALUE),
|
||||
Map.entry(new BigDecimal("9223372036854775807.0"), Long.MAX_VALUE),
|
||||
Map.entry(new BigDecimal("9223372036854775807.00"), Long.MAX_VALUE),
|
||||
|
||||
// 2**63 truncation to -2**63
|
||||
Map.entry(new BigDecimal("-9223372036854775808"), Long.MIN_VALUE),
|
||||
Map.entry(new BigDecimal("-9223372036854775808.1"), Long.MIN_VALUE),
|
||||
Map.entry(new BigDecimal("-9223372036854775808.01"), Long.MIN_VALUE),
|
||||
|
||||
// -2**63 + 1 truncation to 2**63 - 1
|
||||
Map.entry(new BigDecimal("-9223372036854775809"), 9223372036854775807L),
|
||||
|
||||
// 2**64 - 1 truncation to -1
|
||||
Map.entry(new BigDecimal("18446744073709551615"), -1L),
|
||||
|
||||
// 2**64 truncation to 0
|
||||
Map.entry(new BigDecimal("18446744073709551616"), 0L),
|
||||
|
||||
// Slow path truncation to -2**63
|
||||
Map.entry(new BigDecimal("1e63"), -9223372036854775808L),
|
||||
Map.entry(new BigDecimal("-1e63"), -9223372036854775808L),
|
||||
// Fast path with larger magnitude scale
|
||||
Map.entry(new BigDecimal("1e64"), 0L),
|
||||
Map.entry(new BigDecimal("-1e64"), 0L),
|
||||
Map.entry(new BigDecimal("1e65"), 0L),
|
||||
Map.entry(new BigDecimal("-1e65"), 0L),
|
||||
|
||||
// Slow path
|
||||
Map.entry(new BigDecimal("1e0"), 1L),
|
||||
|
||||
// Fast path round to 0
|
||||
Map.entry(new BigDecimal("9e-1"), 0L),
|
||||
|
||||
// Some random values
|
||||
Map.entry(new BigDecimal("900e-1"), 90L), // Increasing negative exponents
|
||||
Map.entry(new BigDecimal("900e-2"), 9L),
|
||||
Map.entry(new BigDecimal("900e-3"), 0L),
|
||||
|
||||
// Fast path round to 0
|
||||
Map.entry(new BigDecimal("123456789e-9"), 0L),
|
||||
|
||||
// Slow path round to 1
|
||||
Map.entry(new BigDecimal("123456789e-8"), 1L),
|
||||
|
||||
// Increasing positive exponents
|
||||
Map.entry(new BigDecimal("10000001e1"), 100000010L),
|
||||
Map.entry(new BigDecimal("10000001e10"), 100000010000000000L),
|
||||
Map.entry(new BigDecimal("10000001e100"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e1000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e10000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e100000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e1000000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e10000000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e100000000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e1000000000"), 0L),
|
||||
|
||||
// Increasing negative exponents
|
||||
Map.entry(new BigDecimal("10000001e-1"), 1000000L),
|
||||
Map.entry(new BigDecimal("10000001e-10"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e-100"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e-1000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e-10000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e-100000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e-1000000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e-10000000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e-100000000"), 0L),
|
||||
Map.entry(new BigDecimal("10000001e-1000000000"), 0L),
|
||||
|
||||
// Currency calculation to 4 places
|
||||
Map.entry(new BigDecimal("12345.0001"), 12345L),
|
||||
Map.entry(new BigDecimal("12345.9999"), 12345L),
|
||||
Map.entry(new BigDecimal("-12345.0001"), -12345L),
|
||||
Map.entry(new BigDecimal("-12345.9999"), -12345L));
|
||||
|
||||
private static int integralValuesTest(Map<BigDecimal, Number> v, boolean isInt) {
|
||||
System.err.format("Testing %s%n", isInt ? "Integer" : "Long");
|
||||
int failures = 0;
|
||||
for (var testCase : v.entrySet()) {
|
||||
BigDecimal bd = testCase.getKey();
|
||||
Number expected = testCase.getValue();
|
||||
try {
|
||||
if (isInt) {
|
||||
int intValue = bd.intValue();
|
||||
if (intValue != (int)expected) {
|
||||
failures += reportError(bd, expected, intValue, isInt);
|
||||
}
|
||||
} else {
|
||||
long longValue = bd.longValue();
|
||||
if (longValue != (long)expected) {
|
||||
failures += reportError(bd, expected, longValue, isInt);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failures++;
|
||||
System.err.format("Unexpected exception %s for %s%n",
|
||||
e, bd.toString());
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int reportError(BigDecimal bd, Number expected, long longValue, boolean isInt) {
|
||||
System.err.format("For %s, scale=%d, expected %d, actual %d, simple %d%n",
|
||||
bd.toString(), bd.scale(),
|
||||
(isInt ? (Integer) expected : (Long) expected ),
|
||||
longValue,
|
||||
(isInt ? simpleIntValue(bd): simpleLongValue(bd) ));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static long simpleLongValue(BigDecimal bd) {
|
||||
return bd.toBigInteger().longValue();
|
||||
}
|
||||
|
||||
private static int simpleIntValue(BigDecimal bd) {
|
||||
return bd.toBigInteger().intValue();
|
||||
}
|
||||
}
|
||||
144
test/jdk/java/math/BigDecimal/LongValueExactTests.java
Normal file
144
test/jdk/java/math/BigDecimal/LongValueExactTests.java
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6806261 8211936 8305343
|
||||
* @summary Tests of BigDecimal.longValueExact
|
||||
*/
|
||||
import java.math.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import static java.util.Map.entry;
|
||||
|
||||
public class LongValueExactTests {
|
||||
public static void main(String... args) {
|
||||
int failures = 0;
|
||||
|
||||
failures += longValueExactSuccessful();
|
||||
failures += longValueExactExceptional();
|
||||
failures += longValueExactExceptional8305343();
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing longValueExact.");
|
||||
}
|
||||
}
|
||||
|
||||
private static long simpleLongValueExact(BigDecimal bd) {
|
||||
return bd.toBigIntegerExact().longValue();
|
||||
}
|
||||
|
||||
private static int longValueExactSuccessful() {
|
||||
int failures = 0;
|
||||
|
||||
// Strings used to create BigDecimal instances on which invoking
|
||||
// longValueExact() will succeed.
|
||||
Map<BigDecimal, Long> successCases =
|
||||
Map.ofEntries(entry(new BigDecimal("9223372036854775807"), Long.MAX_VALUE), // 2^63 -1
|
||||
entry(new BigDecimal("9223372036854775807.0"), Long.MAX_VALUE),
|
||||
entry(new BigDecimal("9223372036854775807.00"), Long.MAX_VALUE),
|
||||
|
||||
entry(new BigDecimal("-9223372036854775808"), Long.MIN_VALUE), // -2^63
|
||||
entry(new BigDecimal("-9223372036854775808.0"), Long.MIN_VALUE),
|
||||
entry(new BigDecimal("-9223372036854775808.00"),Long.MIN_VALUE),
|
||||
|
||||
entry(new BigDecimal("1e0"), 1L),
|
||||
entry(new BigDecimal(BigInteger.ONE, -18), 1_000_000_000_000_000_000L),
|
||||
|
||||
entry(new BigDecimal("0e13"), 0L), // Fast path zero
|
||||
entry(new BigDecimal("0e64"), 0L),
|
||||
entry(new BigDecimal("0e1024"), 0L),
|
||||
|
||||
entry(new BigDecimal("10.000000000000000000000000000000000"), 10L));
|
||||
|
||||
for (var testCase : successCases.entrySet()) {
|
||||
BigDecimal bd = testCase.getKey();
|
||||
long expected = testCase.getValue();
|
||||
try {
|
||||
long longValueExact = bd.longValueExact();
|
||||
if (expected != longValueExact ||
|
||||
longValueExact != simpleLongValueExact(bd)) {
|
||||
failures++;
|
||||
System.err.println("Unexpected longValueExact result " + longValueExact +
|
||||
" on " + bd);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failures++;
|
||||
System.err.println("Error on " + bd + "\tException message:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int longValueExactExceptional() {
|
||||
int failures = 0;
|
||||
List<BigDecimal> exceptionalCases =
|
||||
List.of(new BigDecimal("9223372036854775808"), // Long.MAX_VALUE + 1
|
||||
new BigDecimal("9223372036854775808.0"),
|
||||
new BigDecimal("9223372036854775808.00"),
|
||||
new BigDecimal("-9223372036854775809"), // Long.MIN_VALUE - 1
|
||||
new BigDecimal("-9223372036854775808.1"),
|
||||
new BigDecimal("-9223372036854775808.01"),
|
||||
|
||||
new BigDecimal("9999999999999999999"),
|
||||
new BigDecimal("10000000000000000000"),
|
||||
|
||||
new BigDecimal("0.99"),
|
||||
new BigDecimal("0.999999999999999999999"));
|
||||
|
||||
for (BigDecimal bd : exceptionalCases) {
|
||||
try {
|
||||
long longValueExact = bd.longValueExact();
|
||||
failures++;
|
||||
System.err.println("Unexpected non-exceptional longValueExact on " + bd);
|
||||
} catch (ArithmeticException e) {
|
||||
// Success;
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int longValueExactExceptional8305343() {
|
||||
int failures = 0;
|
||||
List<BigDecimal> exceptionalCases =
|
||||
List.of(new BigDecimal("1e" + (Integer.MAX_VALUE - 1)),
|
||||
new BigDecimal("1e" + (Integer.MAX_VALUE))
|
||||
);
|
||||
|
||||
for (BigDecimal bd : exceptionalCases) {
|
||||
try {
|
||||
bd.longValueExact();
|
||||
failures++;
|
||||
System.err.println("Unexpected non-exceptional longValueExact on " + bd);
|
||||
} catch (ArithmeticException e) {
|
||||
if (!e.getMessage().toLowerCase().contains("overflow")) {
|
||||
failures++;
|
||||
System.err.println("Unexpected non-exceptional longValueExact on " + bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
}
|
||||
106
test/jdk/java/math/BigDecimal/MovePointTests.java
Normal file
106
test/jdk/java/math/BigDecimal/MovePointTests.java
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8289260
|
||||
*/
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class MovePointTests {
|
||||
|
||||
public static void main(String argv[]) {
|
||||
BigDecimal bd;
|
||||
|
||||
bd = BigDecimal.valueOf(1, -3);
|
||||
checkNotIdentical(bd, bd.movePointLeft(0));
|
||||
checkNotIdentical(bd, bd.movePointRight(0));
|
||||
|
||||
bd = BigDecimal.valueOf(1, 0);
|
||||
checkIdentical(bd, bd.movePointLeft(0));
|
||||
checkIdentical(bd, bd.movePointRight(0));
|
||||
|
||||
bd = BigDecimal.valueOf(1, 3);
|
||||
checkIdentical(bd, bd.movePointLeft(0));
|
||||
checkIdentical(bd, bd.movePointRight(0));
|
||||
|
||||
bd = BigDecimal.valueOf(1, -3);
|
||||
checkNotEquals(bd, bd.movePointLeft(1));
|
||||
checkNotEquals(bd, bd.movePointLeft(-1));
|
||||
checkNotEquals(bd, bd.movePointRight(1));
|
||||
checkNotEquals(bd, bd.movePointRight(-1));
|
||||
|
||||
bd = BigDecimal.valueOf(1, 0);
|
||||
checkNotEquals(bd, bd.movePointLeft(1));
|
||||
checkNotEquals(bd, bd.movePointLeft(-1));
|
||||
checkNotEquals(bd, bd.movePointRight(1));
|
||||
checkNotEquals(bd, bd.movePointRight(-1));
|
||||
|
||||
bd = BigDecimal.valueOf(1, 3);
|
||||
checkNotEquals(bd, bd.movePointLeft(1));
|
||||
checkNotEquals(bd, bd.movePointLeft(-1));
|
||||
checkNotEquals(bd, bd.movePointRight(1));
|
||||
checkNotEquals(bd, bd.movePointRight(-1));
|
||||
|
||||
bd = BigDecimal.valueOf(1, -3);
|
||||
checkNotEquals(bd, bd.movePointLeft(10));
|
||||
checkNotEquals(bd, bd.movePointLeft(-10));
|
||||
checkNotEquals(bd, bd.movePointRight(10));
|
||||
checkNotEquals(bd, bd.movePointRight(-10));
|
||||
|
||||
bd = BigDecimal.valueOf(1, 0);
|
||||
checkNotEquals(bd, bd.movePointLeft(10));
|
||||
checkNotEquals(bd, bd.movePointLeft(-10));
|
||||
checkNotEquals(bd, bd.movePointRight(10));
|
||||
checkNotEquals(bd, bd.movePointRight(-10));
|
||||
|
||||
bd = BigDecimal.valueOf(1, 3);
|
||||
checkNotEquals(bd, bd.movePointLeft(10));
|
||||
checkNotEquals(bd, bd.movePointLeft(-10));
|
||||
checkNotEquals(bd, bd.movePointRight(10));
|
||||
checkNotEquals(bd, bd.movePointRight(-10));
|
||||
}
|
||||
|
||||
private static void checkIdentical(BigDecimal bd, BigDecimal res) {
|
||||
if (res != bd) { // intentionally !=
|
||||
throw new RuntimeException("Unexpected result " +
|
||||
bd + " != " + res);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkNotIdentical(BigDecimal bd, BigDecimal res) {
|
||||
if (res == bd) { // intentionally ==
|
||||
throw new RuntimeException("Unexpected result " +
|
||||
bd + " == " + res);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkNotEquals(BigDecimal bd, BigDecimal res) {
|
||||
if (res.equals(bd)) {
|
||||
throw new RuntimeException("Unexpected result " +
|
||||
bd + ".equals(" + res + ")");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
98
test/jdk/java/math/BigDecimal/MultiplyTests.java
Normal file
98
test/jdk/java/math/BigDecimal/MultiplyTests.java
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6850606
|
||||
* @summary Test BigDecimal.multiply(BigDecimal)
|
||||
* @author xlu
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import static java.math.BigDecimal.*;
|
||||
|
||||
public class MultiplyTests {
|
||||
|
||||
private static int multiplyTests() {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal[] bd1 = {
|
||||
new BigDecimal("123456789"),
|
||||
new BigDecimal("1234567898"),
|
||||
new BigDecimal("12345678987")
|
||||
};
|
||||
|
||||
BigDecimal[] bd2 = {
|
||||
new BigDecimal("987654321"),
|
||||
new BigDecimal("8987654321"),
|
||||
new BigDecimal("78987654321")
|
||||
};
|
||||
|
||||
// Two dimensonal array recording bd1[i] * bd2[j] &
|
||||
// 0 <= i <= 2 && 0 <= j <= 2;
|
||||
BigDecimal[][] expectedResults = {
|
||||
{new BigDecimal("121932631112635269"),
|
||||
new BigDecimal("1109586943112635269"),
|
||||
new BigDecimal("9751562173112635269")
|
||||
},
|
||||
{ new BigDecimal("1219326319027587258"),
|
||||
new BigDecimal("11095869503027587258"),
|
||||
new BigDecimal("97515622363027587258")
|
||||
},
|
||||
{ new BigDecimal("12193263197189452827"),
|
||||
new BigDecimal("110958695093189452827"),
|
||||
new BigDecimal("975156224183189452827")
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 0; i < bd1.length; i++) {
|
||||
for (int j = 0; j < bd2.length; j++) {
|
||||
if (!bd1[i].multiply(bd2[j]).equals(expectedResults[i][j])) {
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BigDecimal x = BigDecimal.valueOf(8L, 1);
|
||||
BigDecimal xPower = BigDecimal.valueOf(-1L);
|
||||
try {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
xPower = xPower.multiply(x);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
failures++;
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int failures = 0;
|
||||
|
||||
failures += multiplyTests();
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing multiply.");
|
||||
}
|
||||
}
|
||||
}
|
||||
110
test/jdk/java/math/BigDecimal/NegateTests.java
Normal file
110
test/jdk/java/math/BigDecimal/NegateTests.java
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6325535
|
||||
* @summary Test for the rounding behavior of negate(MathContext)
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
|
||||
public class NegateTests {
|
||||
|
||||
static BigDecimal negateThenRound(BigDecimal bd, MathContext mc) {
|
||||
return bd.negate().plus(mc);
|
||||
}
|
||||
|
||||
|
||||
static BigDecimal absThenRound(BigDecimal bd, MathContext mc) {
|
||||
return bd.abs().plus(mc);
|
||||
}
|
||||
|
||||
|
||||
static int negateTest(BigDecimal[][] testCases, MathContext mc) {
|
||||
int failures = 0;
|
||||
|
||||
for (BigDecimal [] testCase : testCases) {
|
||||
|
||||
BigDecimal bd = testCase[0];
|
||||
BigDecimal neg1 = bd.negate(mc);
|
||||
BigDecimal neg2 = negateThenRound(bd, mc);
|
||||
BigDecimal expected = testCase[1];
|
||||
|
||||
if (! neg1.equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("(" + bd + ").negate(" + mc + ") => " +
|
||||
neg1 + " != expected " + expected);
|
||||
}
|
||||
|
||||
if (! neg1.equals(neg2) ) {
|
||||
failures++;
|
||||
System.err.println("(" + bd + ").negate(" + mc + ") => " +
|
||||
neg1 + " != ntr " + neg2);
|
||||
}
|
||||
|
||||
// Test abs consistency
|
||||
BigDecimal abs = bd.abs(mc);
|
||||
BigDecimal expectedAbs = absThenRound(bd,mc);
|
||||
if (! abs.equals(expectedAbs) ) {
|
||||
failures++;
|
||||
System.err.println("(" + bd + ").abs(" + mc + ") => " +
|
||||
abs + " != atr " + expectedAbs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int negateTests() {
|
||||
int failures = 0;
|
||||
BigDecimal [][] testCasesCeiling = {
|
||||
{new BigDecimal("1.3"), new BigDecimal("-1")},
|
||||
{new BigDecimal("-1.3"), new BigDecimal("2")},
|
||||
};
|
||||
|
||||
failures += negateTest(testCasesCeiling,
|
||||
new MathContext(1, RoundingMode.CEILING));
|
||||
|
||||
BigDecimal [][] testCasesFloor = {
|
||||
{new BigDecimal("1.3"), new BigDecimal("-2")},
|
||||
{new BigDecimal("-1.3"), new BigDecimal("1")},
|
||||
};
|
||||
|
||||
failures += negateTest(testCasesFloor,
|
||||
new MathContext(1, RoundingMode.FLOOR));
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += negateTests();
|
||||
|
||||
if (failures > 0 )
|
||||
throw new RuntimeException("Incurred " + failures + " failures" +
|
||||
" testing the negate and/or abs.");
|
||||
}
|
||||
}
|
||||
95
test/jdk/java/math/BigDecimal/PowTests.java
Normal file
95
test/jdk/java/math/BigDecimal/PowTests.java
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4916097
|
||||
* @summary Some exponent over/undeflow tests for the pow method
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
|
||||
public class PowTests {
|
||||
static int zeroAndOneTests() {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal[][] testCases = {
|
||||
{BigDecimal.valueOf(0, Integer.MAX_VALUE), new BigDecimal(0), BigDecimal.valueOf(1, 0)},
|
||||
{BigDecimal.valueOf(0, Integer.MAX_VALUE), new BigDecimal(1), BigDecimal.valueOf(0, Integer.MAX_VALUE)},
|
||||
{BigDecimal.valueOf(0, Integer.MAX_VALUE), new BigDecimal(2), BigDecimal.valueOf(0, Integer.MAX_VALUE)},
|
||||
{BigDecimal.valueOf(0, Integer.MAX_VALUE), new BigDecimal(999999999), BigDecimal.valueOf(0, Integer.MAX_VALUE)},
|
||||
|
||||
{BigDecimal.valueOf(0, Integer.MIN_VALUE), new BigDecimal(0), BigDecimal.valueOf(1, 0)},
|
||||
{BigDecimal.valueOf(0, Integer.MIN_VALUE), new BigDecimal(1), BigDecimal.valueOf(0, Integer.MIN_VALUE)},
|
||||
{BigDecimal.valueOf(0, Integer.MIN_VALUE), new BigDecimal(2), BigDecimal.valueOf(0, Integer.MIN_VALUE)},
|
||||
{BigDecimal.valueOf(0, Integer.MIN_VALUE), new BigDecimal(999999999), BigDecimal.valueOf(0, Integer.MIN_VALUE)},
|
||||
|
||||
{BigDecimal.valueOf(1, Integer.MAX_VALUE), new BigDecimal(0), BigDecimal.valueOf(1, 0)},
|
||||
{BigDecimal.valueOf(1, Integer.MAX_VALUE), new BigDecimal(1), BigDecimal.valueOf(1, Integer.MAX_VALUE)},
|
||||
{BigDecimal.valueOf(1, Integer.MAX_VALUE), new BigDecimal(2), null}, // overflow
|
||||
{BigDecimal.valueOf(1, Integer.MAX_VALUE), new BigDecimal(999999999), null}, // overflow
|
||||
|
||||
{BigDecimal.valueOf(1, Integer.MIN_VALUE), new BigDecimal(0), BigDecimal.valueOf(1, 0)},
|
||||
{BigDecimal.valueOf(1, Integer.MIN_VALUE), new BigDecimal(1), BigDecimal.valueOf(1, Integer.MIN_VALUE)},
|
||||
{BigDecimal.valueOf(1, Integer.MIN_VALUE), new BigDecimal(2), null}, // underflow
|
||||
{BigDecimal.valueOf(1, Integer.MIN_VALUE), new BigDecimal(999999999), null}, // underflow
|
||||
};
|
||||
|
||||
for(BigDecimal[] testCase: testCases) {
|
||||
int exponent = testCase[1].intValueExact();
|
||||
BigDecimal result;
|
||||
|
||||
try{
|
||||
result = testCase[0].pow(exponent);
|
||||
if (!result.equals(testCase[2]) ) {
|
||||
failures++;
|
||||
System.err.println("Unexpected result while raising " +
|
||||
testCase[0] +
|
||||
" to the " + exponent + " power; expected " +
|
||||
testCase[2] + ", got " + result + ".");
|
||||
}
|
||||
} catch (ArithmeticException e) {
|
||||
if (testCase[2] != null) {
|
||||
failures++;
|
||||
System.err.println("Unexpected exception while raising " + testCase[0] +
|
||||
" to the " + exponent + " power.");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += zeroAndOneTests();
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing pow methods.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
93
test/jdk/java/math/BigDecimal/PrecisionTests.java
Normal file
93
test/jdk/java/math/BigDecimal/PrecisionTests.java
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 1234567
|
||||
* @summary Test that precision() is computed properly.
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import static java.math.BigDecimal.*;
|
||||
|
||||
public class PrecisionTests {
|
||||
private static BigDecimal NINE = valueOf(9);
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
// Smallest and largest values of a given length
|
||||
BigDecimal[] testValues = {
|
||||
valueOf(1), valueOf(9),
|
||||
};
|
||||
|
||||
failures += testPrecision(new BigDecimal(0), 1);
|
||||
|
||||
for(int i = 1; i < 100; i++) {
|
||||
for(BigDecimal bd : testValues) {
|
||||
failures += testPrecision(bd, i);
|
||||
failures += testPrecision(bd.negate(), i);
|
||||
}
|
||||
|
||||
testValues[0] = testValues[0].multiply(TEN);
|
||||
testValues[1] = testValues[1].multiply(TEN).add(NINE);
|
||||
}
|
||||
|
||||
// The following test tries to cover testings for precision of long values
|
||||
BigDecimal[] randomTestValues = {
|
||||
valueOf(2147483648L), // 2^31: 10 digits
|
||||
valueOf(-2147483648L), // -2^31: 10 digits
|
||||
valueOf(98893745455L), // random: 11 digits
|
||||
valueOf(3455436789887L), // random: 13 digits
|
||||
valueOf(140737488355328L), // 2^47: 15 digits
|
||||
valueOf(-140737488355328L), // -2^47: 15 digits
|
||||
valueOf(7564232235739573L), // random: 16 digits
|
||||
valueOf(25335434990002322L), // random: 17 digits
|
||||
valueOf(9223372036854775807L), // 2^63 - 1: 19 digits
|
||||
valueOf(-9223372036854775807L) // -2^63 + 1: 19 digits
|
||||
};
|
||||
// The array below contains the expected precision of the above numbers
|
||||
int[] expectedPrecision = {10, 10, 11, 13, 15, 15, 16, 17, 19, 19};
|
||||
for (int i = 0; i < randomTestValues.length; i++) {
|
||||
failures += testPrecision(randomTestValues[i], expectedPrecision[i]);
|
||||
}
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing precision.");
|
||||
}
|
||||
}
|
||||
|
||||
private static int testPrecision(BigDecimal bd, int expected) {
|
||||
int precision = bd.precision();
|
||||
|
||||
// System.out.printf("Testing %s, expected %d%n", bd, expected);
|
||||
|
||||
if (precision != expected) {
|
||||
System.err.printf("For (%s).precision expected %d, got %d%n",
|
||||
bd, expected, precision);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
245
test/jdk/java/math/BigDecimal/RangeTests.java
Normal file
245
test/jdk/java/math/BigDecimal/RangeTests.java
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7036582
|
||||
* @summary Some new tests for the add method and constructor with MathContext.
|
||||
* @run main RangeTests
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox -XX:AutoBoxCacheMax=20000 RangeTests
|
||||
* @author Sergey V. Kuksenko
|
||||
*/
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
|
||||
public class RangeTests {
|
||||
|
||||
|
||||
private static int addTest(BigDecimal arg1, BigDecimal arg2, BigDecimal expectedResult) {
|
||||
int failures = 0;
|
||||
BigDecimal result = arg1.add(arg2);
|
||||
if (!result.equals(expectedResult)) {
|
||||
System.out.println("Sum:" +
|
||||
arg1 + " + " +
|
||||
arg2 + " == " +
|
||||
result + "; expected " +
|
||||
expectedResult
|
||||
);
|
||||
failures++;
|
||||
}
|
||||
result = arg2.add(arg1);
|
||||
if (!result.equals(expectedResult)) {
|
||||
System.out.println("Sum:" +
|
||||
arg2 + " + " +
|
||||
arg1 + " == " +
|
||||
result + "; expected " +
|
||||
expectedResult
|
||||
);
|
||||
failures++;
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test BigDecimal.add(BigDecimal) when values are withing different ranges:
|
||||
* 1. within 32 bits
|
||||
* 2. within 64 bits
|
||||
* 3. outside 64 bits.
|
||||
*/
|
||||
private static int addBoundaryTest() {
|
||||
int failures = 0;
|
||||
failures += addTest(
|
||||
new BigDecimal("85070591730234615847396907784232501249"),
|
||||
BigDecimal.valueOf(0),
|
||||
new BigDecimal("85070591730234615847396907784232501249") );
|
||||
failures += addTest(
|
||||
new BigDecimal("-85070591730234615847396907784232501249"),
|
||||
BigDecimal.valueOf(0),
|
||||
new BigDecimal("-85070591730234615847396907784232501249") );
|
||||
failures += addTest(
|
||||
new BigDecimal("85070591730234615847396907784232501249"),
|
||||
BigDecimal.valueOf(1),
|
||||
new BigDecimal("85070591730234615847396907784232501250") );
|
||||
failures += addTest(
|
||||
new BigDecimal("85070591730234615847396907784232501249"),
|
||||
BigDecimal.valueOf(-1),
|
||||
new BigDecimal("85070591730234615847396907784232501248") );
|
||||
failures += addTest(
|
||||
new BigDecimal("-85070591730234615847396907784232501250"),
|
||||
BigDecimal.valueOf(-1),
|
||||
new BigDecimal("-85070591730234615847396907784232501251") );
|
||||
failures += addTest(
|
||||
new BigDecimal("-85070591730234615847396907784232501249"),
|
||||
BigDecimal.valueOf(1),
|
||||
new BigDecimal("-85070591730234615847396907784232501248") );
|
||||
failures += addTest(
|
||||
new BigDecimal("147573952589676412927"),
|
||||
BigDecimal.valueOf(Integer.MAX_VALUE),
|
||||
new BigDecimal("147573952591823896574") );
|
||||
failures += addTest(
|
||||
new BigDecimal("-147573952589676412927"),
|
||||
BigDecimal.valueOf(Integer.MAX_VALUE),
|
||||
new BigDecimal("-147573952587528929280") );
|
||||
failures += addTest(
|
||||
new BigDecimal("79228162514264337593543950335"),
|
||||
BigDecimal.valueOf(999),
|
||||
new BigDecimal("79228162514264337593543951334") );
|
||||
failures += addTest(
|
||||
new BigDecimal("79228162514264337593543950335"),
|
||||
BigDecimal.valueOf(Integer.MAX_VALUE/2),
|
||||
new BigDecimal("79228162514264337594617692158") );
|
||||
failures += addTest(
|
||||
new BigDecimal("79228162514264337593543950335"),
|
||||
BigDecimal.valueOf(Integer.MIN_VALUE/2),
|
||||
new BigDecimal("79228162514264337592470208511") );
|
||||
failures += addTest(
|
||||
new BigDecimal("-79228162514264337593543950335"),
|
||||
BigDecimal.valueOf(Integer.MAX_VALUE/2),
|
||||
new BigDecimal("-79228162514264337592470208512") );
|
||||
failures += addTest(
|
||||
new BigDecimal("79228162514264337593543950335"),
|
||||
BigDecimal.valueOf(-(Integer.MIN_VALUE/2)),
|
||||
new BigDecimal("79228162514264337594617692159") );
|
||||
failures += addTest(
|
||||
new BigDecimal("79228162514264337593543950335"),
|
||||
BigDecimal.valueOf(Long.MAX_VALUE/2),
|
||||
new BigDecimal("79228162518876023611971338238") );
|
||||
failures += addTest(
|
||||
new BigDecimal("79228162514264337593543950335"),
|
||||
BigDecimal.valueOf(Long.MIN_VALUE/2),
|
||||
new BigDecimal("79228162509652651575116562431") );
|
||||
failures += addTest(
|
||||
new BigDecimal("-79228162514264337593543950335"),
|
||||
BigDecimal.valueOf(Long.MAX_VALUE/2),
|
||||
new BigDecimal("-79228162509652651575116562432") );
|
||||
failures += addTest(
|
||||
new BigDecimal("79228162514264337593543950335"),
|
||||
BigDecimal.valueOf(-(Long.MIN_VALUE/2)),
|
||||
new BigDecimal("79228162518876023611971338239") );
|
||||
failures += addTest(
|
||||
new BigDecimal("-9223372036854775808"),
|
||||
BigDecimal.valueOf(1),
|
||||
new BigDecimal("-9223372036854775807") );
|
||||
failures += addTest(
|
||||
new BigDecimal("-9223372036854775808"),
|
||||
BigDecimal.valueOf(Long.MAX_VALUE/2),
|
||||
new BigDecimal("-4611686018427387905") );
|
||||
failures += addTest(
|
||||
new BigDecimal("9223372036854775808"),
|
||||
BigDecimal.valueOf(-1),
|
||||
new BigDecimal("9223372036854775807") );
|
||||
failures += addTest(
|
||||
new BigDecimal("9223372036854775808"),
|
||||
BigDecimal.valueOf(-Long.MAX_VALUE/2),
|
||||
new BigDecimal("4611686018427387905") );
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int testRoundingFromBigInteger(BigInteger bi, int scale, MathContext mc) {
|
||||
int failures = 0;
|
||||
BigDecimal bd1 = new BigDecimal(bi,scale, mc);
|
||||
BigDecimal bd2 = (new BigDecimal(bi,scale)).round(mc);
|
||||
if (!bd1.equals(bd2)) {
|
||||
System.out.println("new BigDecimal(BigInteger,int,MathContext):" +
|
||||
"BigInteger == " +
|
||||
bi + "; scale == " + scale + "; result == " +
|
||||
bd1 + "; expected == " +
|
||||
bd2
|
||||
);
|
||||
failures++;
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int roundingConstructorTest() {
|
||||
int failures = 0;
|
||||
failures += testRoundingFromBigInteger(
|
||||
new BigInteger("85070591730234615847396907784232501249"),
|
||||
7, MathContext.DECIMAL64);
|
||||
failures += testRoundingFromBigInteger(
|
||||
new BigInteger("85070591730234615847396907784232501249"),
|
||||
0, MathContext.DECIMAL64);
|
||||
failures += testRoundingFromBigInteger(
|
||||
new BigInteger("85070591730234615847396907784232501249"),
|
||||
-7, MathContext.DECIMAL64);
|
||||
failures += testRoundingFromBigInteger(
|
||||
new BigInteger("85070591730234615847396907784232501249"),
|
||||
7, MathContext.DECIMAL128);
|
||||
failures += testRoundingFromBigInteger(
|
||||
new BigInteger("85070591730234615847396907784232501249"),
|
||||
177, MathContext.DECIMAL128);
|
||||
failures += testRoundingFromBigInteger(
|
||||
new BigInteger("85070591730234615847396907784232501249"),
|
||||
177, MathContext.DECIMAL32);
|
||||
failures += testRoundingFromBigInteger(
|
||||
new BigInteger("85070591730234615847396907784232501249"),
|
||||
177, MathContext.UNLIMITED);
|
||||
failures += testRoundingFromBigInteger(
|
||||
new BigInteger("85070591730234615847396907784232501249"),
|
||||
0, MathContext.UNLIMITED);
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int minLongConstructorTest(MathContext mc) {
|
||||
int failures = 0;
|
||||
BigDecimal bd1 = new BigDecimal(Long.MIN_VALUE,mc);
|
||||
BigDecimal bd2 = new BigDecimal(Long.MIN_VALUE).round(mc);
|
||||
if (!bd1.equals(bd2)) {
|
||||
System.out.println("new BigDecimal(long,MathContext):" +
|
||||
"long == " +
|
||||
Long.MIN_VALUE + "; result == " +
|
||||
bd1 + "; expected == " +
|
||||
bd2
|
||||
);
|
||||
failures++;
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int minLongConstructorTest() {
|
||||
int failures = 0;
|
||||
failures+=minLongConstructorTest(MathContext.UNLIMITED);
|
||||
failures+=minLongConstructorTest(MathContext.DECIMAL32);
|
||||
failures+=minLongConstructorTest(MathContext.DECIMAL64);
|
||||
failures+=minLongConstructorTest(MathContext.DECIMAL128);
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += addBoundaryTest();
|
||||
failures += roundingConstructorTest();
|
||||
failures += minLongConstructorTest();
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
58
test/jdk/java/math/BigDecimal/RoundingTests.java
Normal file
58
test/jdk/java/math/BigDecimal/RoundingTests.java
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6334849
|
||||
* @summary Tests of dropping digits near the scale threshold
|
||||
*/
|
||||
import java.math.*;
|
||||
public class RoundingTests {
|
||||
private static int roundingTests() {
|
||||
int failures = 0;
|
||||
BigDecimal bd1 = BigDecimal.valueOf(11, Integer.MIN_VALUE);
|
||||
BigDecimal bd2 = null;
|
||||
MathContext mc = new MathContext(1);
|
||||
try {
|
||||
bd2 = bd1.round(mc); // should overflow here
|
||||
failures++;
|
||||
System.err.printf("Did not get expected overflow rounding %s to %d digits, got %s%n",
|
||||
bd1, mc.getPrecision(), bd2);
|
||||
} catch(ArithmeticException e) {
|
||||
; // expected
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += roundingTests();
|
||||
|
||||
if (failures > 0) {
|
||||
System.err.println("Encountered " + failures +
|
||||
" failures while testing rounding.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
57
test/jdk/java/math/BigDecimal/ScaleByPowerOfTenTests.java
Normal file
57
test/jdk/java/math/BigDecimal/ScaleByPowerOfTenTests.java
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4899722
|
||||
* @summary Basic tests of scaleByPowerOfTen
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
|
||||
public class ScaleByPowerOfTenTests {
|
||||
|
||||
public static void main(String argv[]) {
|
||||
for (int i = -10; i < 10; i++) {
|
||||
BigDecimal bd = BigDecimal.ONE.scaleByPowerOfTen(i);
|
||||
BigDecimal expected;
|
||||
|
||||
if (!bd.equals(expected = new BigDecimal(BigInteger.ONE, -i))) {
|
||||
throw new RuntimeException("Unexpected result " +
|
||||
bd.toString() +
|
||||
"; expected " +
|
||||
expected.toString());
|
||||
}
|
||||
|
||||
bd = BigDecimal.ONE.negate().scaleByPowerOfTen(i);
|
||||
if (!bd.equals(expected = new BigDecimal(BigInteger.ONE.negate(), -i))) {
|
||||
throw new RuntimeException("Unexpected result " +
|
||||
bd.toString() +
|
||||
"; expected " +
|
||||
expected.toString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
150
test/jdk/java/math/BigDecimal/SerializationTests.java
Normal file
150
test/jdk/java/math/BigDecimal/SerializationTests.java
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6177836 8282252
|
||||
* @summary Verify BigDecimal objects with collapsed values are serialized properly.
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
|
||||
public class SerializationTests {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
checkBigDecimalSerialRoundTrip();
|
||||
checkBigDecimalSubSerialRoundTrip();
|
||||
}
|
||||
|
||||
private static void checkSerialForm(BigDecimal bd) throws Exception {
|
||||
checkSerialForm0(bd);
|
||||
checkSerialForm0(bd.negate());
|
||||
}
|
||||
|
||||
private static void checkSerialForm0(BigDecimal bd) throws Exception {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
try(ObjectOutputStream oos = new ObjectOutputStream(bos)) {
|
||||
oos.writeObject(bd);
|
||||
oos.flush();
|
||||
}
|
||||
|
||||
ObjectInputStream ois = new
|
||||
ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
|
||||
BigDecimal tmp = (BigDecimal)ois.readObject();
|
||||
|
||||
if (!bd.equals(tmp) ||
|
||||
bd.hashCode() != tmp.hashCode() ||
|
||||
bd.getClass() != tmp.getClass() ||
|
||||
// Directly test equality of components
|
||||
bd.scale() != tmp.scale() ||
|
||||
!bd.unscaledValue().equals(tmp.unscaledValue())) {
|
||||
System.err.print(" original : " + bd);
|
||||
System.err.println(" (hash: 0x" + Integer.toHexString(bd.hashCode()) + ")");
|
||||
System.err.print("serialized : " + tmp);
|
||||
System.err.println(" (hash: 0x" + Integer.toHexString(tmp.hashCode()) + ")");
|
||||
throw new RuntimeException("Bad serial roundtrip");
|
||||
}
|
||||
|
||||
// If the class of the deserialized number is BigDecimal,
|
||||
// verify the implementation constraint on the unscaled value
|
||||
// having BigInteger class
|
||||
if (tmp.getClass() == BigDecimal.class) {
|
||||
if (tmp.unscaledValue().getClass() != BigInteger.class) {
|
||||
throw new RuntimeException("Not using genuine BigInteger as an unscaled value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class BigIntegerSub extends BigInteger {
|
||||
public BigIntegerSub(BigInteger bi) {
|
||||
super(bi.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return java.util.Arrays.toString(toByteArray());
|
||||
}
|
||||
}
|
||||
private static void checkBigDecimalSerialRoundTrip() throws Exception {
|
||||
var values =
|
||||
List.of(BigDecimal.ZERO,
|
||||
BigDecimal.ONE,
|
||||
BigDecimal.TEN,
|
||||
new BigDecimal(0),
|
||||
new BigDecimal(1),
|
||||
new BigDecimal(10),
|
||||
new BigDecimal(Integer.MAX_VALUE),
|
||||
new BigDecimal(Long.MAX_VALUE-1),
|
||||
new BigDecimal(BigInteger.valueOf(1), 1),
|
||||
new BigDecimal(BigInteger.valueOf(100), 50),
|
||||
new BigDecimal(new BigInteger("9223372036854775808"), // Long.MAX_VALUE + 1
|
||||
Integer.MAX_VALUE),
|
||||
new BigDecimal(new BigInteger("9223372036854775808"), // Long.MAX_VALUE + 1
|
||||
Integer.MIN_VALUE),
|
||||
new BigDecimal(new BigIntegerSub(BigInteger.ONE), 2));
|
||||
|
||||
for(BigDecimal value : values) {
|
||||
checkSerialForm(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static class BigDecimalSub extends BigDecimal {
|
||||
public BigDecimalSub(BigDecimal bd) {
|
||||
super(bd.unscaledValue(), bd.scale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return unscaledValue() + "x10^" + (-scale());
|
||||
}
|
||||
}
|
||||
|
||||
// Subclass defining a serialVersionUID
|
||||
private static class BigDecimalSubSVUID extends BigDecimal {
|
||||
@java.io.Serial
|
||||
private static long serialVesionUID = 0x0123_4567_89ab_cdefL;
|
||||
|
||||
public BigDecimalSubSVUID(BigDecimal bd) {
|
||||
super(bd.unscaledValue(), bd.scale());
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkBigDecimalSubSerialRoundTrip() throws Exception {
|
||||
var values =
|
||||
List.of(BigDecimal.ZERO,
|
||||
BigDecimal.ONE,
|
||||
BigDecimal.TEN,
|
||||
new BigDecimal(BigInteger.TEN, 1234),
|
||||
new BigDecimal(new BigInteger("9223372036854775808"), // Long.MAX_VALUE + 1
|
||||
Integer.MAX_VALUE),
|
||||
new BigDecimal(new BigInteger("9223372036854775808"), // Long.MAX_VALUE + 1
|
||||
Integer.MIN_VALUE));
|
||||
|
||||
for(var value : values) {
|
||||
checkSerialForm(new BigDecimalSub(value));
|
||||
checkSerialForm(new BigDecimalSubSVUID(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
834
test/jdk/java/math/BigDecimal/SquareRootTests.java
Normal file
834
test/jdk/java/math/BigDecimal/SquareRootTests.java
Normal file
|
|
@ -0,0 +1,834 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4851777 8233452 8341402
|
||||
* @summary Tests of BigDecimal.sqrt().
|
||||
*/
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
|
||||
import static java.math.BigDecimal.ONE;
|
||||
import static java.math.BigDecimal.TWO;
|
||||
import static java.math.BigDecimal.TEN;
|
||||
import static java.math.BigDecimal.ZERO;
|
||||
import static java.math.BigDecimal.valueOf;
|
||||
|
||||
public class SquareRootTests {
|
||||
/**
|
||||
* The value 0.1, with a scale of 1.
|
||||
*/
|
||||
private static final BigDecimal ONE_TENTH = valueOf(1L, 1);
|
||||
|
||||
public static void main(String... args) {
|
||||
int failures = 0;
|
||||
|
||||
failures += negativeTests();
|
||||
failures += zeroTests();
|
||||
failures += oneDigitTests();
|
||||
failures += twoDigitTests();
|
||||
failures += evenPowersOfTenTests();
|
||||
failures += squareRootTwoTests();
|
||||
failures += lowPrecisionPerfectSquares();
|
||||
failures += almostFourRoundingDown();
|
||||
failures += almostFourRoundingUp();
|
||||
failures += nearTen();
|
||||
failures += nearOne();
|
||||
failures += halfWay();
|
||||
failures += exactResultTests();
|
||||
failures += scaleOverflowTest();
|
||||
|
||||
if (failures > 0 ) {
|
||||
throw new RuntimeException("Incurred " + failures + " failures" +
|
||||
" testing BigDecimal.sqrt().");
|
||||
}
|
||||
}
|
||||
|
||||
private static int negativeTests() {
|
||||
int failures = 0;
|
||||
|
||||
for (long i = -10; i < 0; i++) {
|
||||
for (int j = -5; j < 5; j++) {
|
||||
try {
|
||||
BigDecimal input = BigDecimal.valueOf(i, j);
|
||||
BigDecimal result = input.sqrt(MathContext.DECIMAL64);
|
||||
System.err.println("Unexpected sqrt of negative: (" +
|
||||
input + ").sqrt() = " + result );
|
||||
failures += 1;
|
||||
} catch (ArithmeticException e) {
|
||||
; // Expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int zeroTests() {
|
||||
int failures = 0;
|
||||
|
||||
for (int i = -100; i < 100; i++) {
|
||||
BigDecimal expected = BigDecimal.valueOf(0L, i/2);
|
||||
// These results are independent of rounding mode
|
||||
failures += compare(BigDecimal.valueOf(0L, i).sqrt(MathContext.UNLIMITED),
|
||||
expected, true, "zeros");
|
||||
|
||||
failures += compare(BigDecimal.valueOf(0L, i).sqrt(MathContext.DECIMAL64),
|
||||
expected, true, "zeros");
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Probe inputs with one digit of precision, 1 ... 9 and those
|
||||
* values scaled by 10^-1, 0.1, ... 0.9.
|
||||
*/
|
||||
private static int oneDigitTests() {
|
||||
int failures = 0;
|
||||
|
||||
List<BigDecimal> oneToNine =
|
||||
List.of(ONE, TWO, valueOf(3),
|
||||
valueOf(4), valueOf(5), valueOf(6),
|
||||
valueOf(7), valueOf(8), valueOf(9));
|
||||
|
||||
List<RoundingMode> modes =
|
||||
List.of(RoundingMode.UP, RoundingMode.DOWN,
|
||||
RoundingMode.CEILING, RoundingMode.FLOOR,
|
||||
RoundingMode.HALF_UP, RoundingMode.HALF_DOWN, RoundingMode.HALF_EVEN);
|
||||
|
||||
for (int i = 1; i < 20; i++) {
|
||||
for (RoundingMode rm : modes) {
|
||||
for (BigDecimal bd : oneToNine) {
|
||||
MathContext mc = new MathContext(i, rm);
|
||||
|
||||
failures += compareSqrtImplementations(bd, mc);
|
||||
bd = bd.multiply(ONE_TENTH);
|
||||
failures += compareSqrtImplementations(bd, mc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Probe inputs with two digits of precision, (10 ... 99) and
|
||||
* those values scaled by 10^-1 (1, ... 9.9) and scaled by 10^-2
|
||||
* (0.1 ... 0.99).
|
||||
*/
|
||||
private static int twoDigitTests() {
|
||||
int failures = 0;
|
||||
|
||||
List<RoundingMode> modes =
|
||||
List.of(RoundingMode.UP, RoundingMode.DOWN,
|
||||
RoundingMode.CEILING, RoundingMode.FLOOR,
|
||||
RoundingMode.HALF_UP, RoundingMode.HALF_DOWN, RoundingMode.HALF_EVEN);
|
||||
|
||||
for (int i = 10; i < 100; i++) {
|
||||
BigDecimal bd0 = BigDecimal.valueOf(i);
|
||||
BigDecimal bd1 = bd0.multiply(ONE_TENTH);
|
||||
BigDecimal bd2 = bd1.multiply(ONE_TENTH);
|
||||
|
||||
for (BigDecimal bd : List.of(bd0, bd1, bd2)) {
|
||||
for (int precision = 1; i < 20; i++) {
|
||||
for (RoundingMode rm : modes) {
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
failures += compareSqrtImplementations(bd, mc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int compareSqrtImplementations(BigDecimal bd, MathContext mc) {
|
||||
return equalNumerically(BigSquareRoot.sqrt(bd, mc),
|
||||
bd.sqrt(mc), "sqrt(" + bd + ") under " + mc);
|
||||
}
|
||||
|
||||
private static int exactResultTests() {
|
||||
int failures = 0;
|
||||
MathContext unnecessary = new MathContext(1, RoundingMode.UNNECESSARY);
|
||||
MathContext arbitrary = new MathContext(0, RoundingMode.CEILING);
|
||||
|
||||
BigDecimal[] errCases = {
|
||||
// (strippedScale & 1) != 0
|
||||
BigDecimal.TEN,
|
||||
// (strippedScale & 1) == 0 && !stripped.isPowerOfTen() && sqrtRem[1].signum != 0
|
||||
BigDecimal.TWO,
|
||||
};
|
||||
|
||||
for (BigDecimal input : errCases) {
|
||||
BigDecimal result;
|
||||
// mc.roundingMode == RoundingMode.UNNECESSARY
|
||||
try {
|
||||
result = input.sqrt(unnecessary);
|
||||
System.err.println("Unexpected sqrt with UNNECESSARY RoundingMode: (" + input + ").sqrt() = " + result);
|
||||
failures += 1;
|
||||
} catch (ArithmeticException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
// mc.roundingMode != RoundingMode.UNNECESSARY && mc.precision == 0
|
||||
try {
|
||||
result = input.sqrt(arbitrary);
|
||||
System.err.println("Unexpected sqrt with mc.precision == 0: (" + input + ").sqrt() = " + result);
|
||||
failures += 1;
|
||||
} catch (ArithmeticException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
// (strippedScale & 1) == 0
|
||||
|
||||
// !stripped.isPowerOfTen() && sqrtRem[1].signum == 0 && (mc.precision != 0 && result.precision() > mc.precision)
|
||||
try {
|
||||
BigDecimal input = BigDecimal.valueOf(121);
|
||||
BigDecimal result = input.sqrt(unnecessary);
|
||||
System.err.println("Unexpected sqrt with result.precision() > mc.precision: ("
|
||||
+ input + ").sqrt() = " + result);
|
||||
failures += 1;
|
||||
} catch (ArithmeticException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
BigDecimal four = BigDecimal.valueOf(4);
|
||||
Object[][] cases = {
|
||||
// stripped.isPowerOfTen() && mc.roundingMode == RoundingMode.UNNECESSARY
|
||||
{ BigDecimal.ONE, unnecessary, BigDecimal.ONE },
|
||||
// stripped.isPowerOfTen() && mc.roundingMode != RoundingMode.UNNECESSARY && mc.precision == 0
|
||||
{ BigDecimal.ONE, arbitrary, BigDecimal.ONE },
|
||||
// !stripped.isPowerOfTen() && mc.roundingMode == RoundingMode.UNNECESSARY
|
||||
// && sqrtRem[1].signum == 0 && mc.precision == 0
|
||||
{ four, new MathContext(0, RoundingMode.UNNECESSARY), BigDecimal.TWO },
|
||||
// !stripped.isPowerOfTen() && mc.roundingMode != RoundingMode.UNNECESSARY
|
||||
// && sqrtRem[1].signum == 0 && mc.precision == 0
|
||||
{ four, arbitrary, BigDecimal.TWO },
|
||||
// !stripped.isPowerOfTen() && sqrtRem[1].signum == 0
|
||||
// && (mc.precision != 0 && result.precision() <= mc.precision)
|
||||
{ four, unnecessary, BigDecimal.TWO },
|
||||
};
|
||||
|
||||
for (Object[] testCase : cases) {
|
||||
BigDecimal expected = (BigDecimal) testCase[2];
|
||||
BigDecimal result = ((BigDecimal) testCase[0]).sqrt((MathContext) testCase[1]);
|
||||
failures += compare(expected, result, true, "Exact results");
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int scaleOverflowTest() {
|
||||
int failures = 0;
|
||||
|
||||
try {
|
||||
BigDecimal.valueOf(1, -1).sqrt(new MathContext((1 << 30) + 1, RoundingMode.UP));
|
||||
System.err.println("ArithmeticException expected: possible overflow undetected "
|
||||
+ "or the range of supported values for the algorithm has extended.");
|
||||
failures += 1;
|
||||
} catch (ArithmeticException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* sqrt(10^2N) is 10^N
|
||||
* Both numerical value and representation should be verified
|
||||
*/
|
||||
private static int evenPowersOfTenTests() {
|
||||
int failures = 0;
|
||||
MathContext oneDigitExactly = new MathContext(1, RoundingMode.UNNECESSARY);
|
||||
|
||||
for (int scale = -100; scale <= 100; scale++) {
|
||||
BigDecimal testValue = BigDecimal.valueOf(1, 2*scale);
|
||||
BigDecimal expectedNumericalResult = BigDecimal.valueOf(1, scale);
|
||||
|
||||
BigDecimal result;
|
||||
|
||||
failures += equalNumerically(expectedNumericalResult,
|
||||
result = testValue.sqrt(MathContext.DECIMAL64),
|
||||
"Even powers of 10, DECIMAL64");
|
||||
|
||||
// Can round to one digit of precision exactly
|
||||
failures += equalNumerically(expectedNumericalResult,
|
||||
result = testValue.sqrt(oneDigitExactly),
|
||||
"even powers of 10, 1 digit");
|
||||
|
||||
if (result.precision() > 1) {
|
||||
failures += 1;
|
||||
System.err.println("Excess precision for " + result);
|
||||
}
|
||||
|
||||
// If rounding to more than one digit, do precision / scale checking...
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int squareRootTwoTests() {
|
||||
int failures = 0;
|
||||
|
||||
// Square root of 2 truncated to 65 digits
|
||||
BigDecimal highPrecisionRoot2 =
|
||||
new BigDecimal("1.41421356237309504880168872420969807856967187537694807317667973799");
|
||||
|
||||
RoundingMode[] modes = {
|
||||
RoundingMode.UP, RoundingMode.DOWN,
|
||||
RoundingMode.CEILING, RoundingMode.FLOOR,
|
||||
RoundingMode.HALF_UP, RoundingMode.HALF_DOWN, RoundingMode.HALF_EVEN
|
||||
};
|
||||
|
||||
|
||||
// For each interesting rounding mode, for precisions 1 to, say,
|
||||
// 63 numerically compare TWO.sqrt(mc) to
|
||||
// highPrecisionRoot2.round(mc) and the alternative internal high-precision
|
||||
// implementation of square root.
|
||||
for (RoundingMode mode : modes) {
|
||||
for (int precision = 1; precision < 63; precision++) {
|
||||
MathContext mc = new MathContext(precision, mode);
|
||||
BigDecimal expected = highPrecisionRoot2.round(mc);
|
||||
BigDecimal computed = TWO.sqrt(mc);
|
||||
BigDecimal altComputed = BigSquareRoot.sqrt(TWO, mc);
|
||||
|
||||
failures += equalNumerically(expected, computed, "sqrt(2)");
|
||||
failures += equalNumerically(computed, altComputed, "computed & altComputed");
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int lowPrecisionPerfectSquares() {
|
||||
int failures = 0;
|
||||
|
||||
// For 5^2 through 9^2, if the input is rounded to one digit
|
||||
// first before the root is computed, the wrong answer will
|
||||
// result. Verify results and scale for different rounding
|
||||
// modes and precisions.
|
||||
long[][] squaresWithOneDigitRoot = {{ 4, 2},
|
||||
{ 9, 3},
|
||||
{25, 5},
|
||||
{36, 6},
|
||||
{49, 7},
|
||||
{64, 8},
|
||||
{81, 9}};
|
||||
|
||||
for (long[] squareAndRoot : squaresWithOneDigitRoot) {
|
||||
BigDecimal square = new BigDecimal(squareAndRoot[0]);
|
||||
BigDecimal expected = new BigDecimal(squareAndRoot[1]);
|
||||
|
||||
for (int scale = 0; scale <= 4; scale++) {
|
||||
BigDecimal scaledSquare = square.setScale(scale, RoundingMode.UNNECESSARY);
|
||||
int expectedScale = Math.ceilDiv(scale, 2);
|
||||
for (int precision = 0; precision <= 5; precision++) {
|
||||
for (RoundingMode rm : RoundingMode.values()) {
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
BigDecimal computedRoot = scaledSquare.sqrt(mc);
|
||||
failures += equalNumerically(expected, computedRoot, "simple squares");
|
||||
int computedScale = computedRoot.scale();
|
||||
if (precision >= expectedScale + 1 &&
|
||||
computedScale != expectedScale) {
|
||||
System.err.printf("%s\tprecision=%d\trm=%s%n",
|
||||
computedRoot.toString(), precision, rm);
|
||||
failures++;
|
||||
System.err.printf("\t%s does not have expected scale of %d%n.",
|
||||
computedRoot, expectedScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test around 3.9999 that the sqrt doesn't improperly round-up to
|
||||
* a numerical value of 2.
|
||||
*/
|
||||
private static int almostFourRoundingDown() {
|
||||
int failures = 0;
|
||||
BigDecimal nearFour = new BigDecimal("3.999999999999999999999999999999");
|
||||
|
||||
// Sqrt is 1.9999...
|
||||
|
||||
for (int i = 1; i < 64; i++) {
|
||||
MathContext mc = new MathContext(i, RoundingMode.FLOOR);
|
||||
BigDecimal result = nearFour.sqrt(mc);
|
||||
BigDecimal expected = BigSquareRoot.sqrt(nearFour, mc);
|
||||
failures += equalNumerically(expected, result, "near four rounding down");
|
||||
failures += (result.compareTo(TWO) < 0) ? 0 : 1 ;
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test around 4.000...1 that the sqrt doesn't improperly
|
||||
* round-down to a numerical value of 2.
|
||||
*/
|
||||
private static int almostFourRoundingUp() {
|
||||
int failures = 0;
|
||||
BigDecimal nearFour = new BigDecimal("4.000000000000000000000000000001");
|
||||
|
||||
// Sqrt is 2.0000....<non-zero digits>
|
||||
|
||||
for (int i = 1; i < 64; i++) {
|
||||
MathContext mc = new MathContext(i, RoundingMode.CEILING);
|
||||
BigDecimal result = nearFour.sqrt(mc);
|
||||
BigDecimal expected = BigSquareRoot.sqrt(nearFour, mc);
|
||||
failures += equalNumerically(expected, result, "near four rounding up");
|
||||
failures += (result.compareTo(TWO) > 0) ? 0 : 1 ;
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int nearTen() {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal near10 = new BigDecimal("9.99999999999999999999");
|
||||
|
||||
BigDecimal near10sq = near10.multiply(near10);
|
||||
|
||||
BigDecimal near10sq_ulp = near10sq.add(near10sq.ulp());
|
||||
|
||||
for (int i = 10; i < 23; i++) {
|
||||
MathContext mc = new MathContext(i, RoundingMode.HALF_EVEN);
|
||||
|
||||
failures += equalNumerically(BigSquareRoot.sqrt(near10sq_ulp, mc),
|
||||
near10sq_ulp.sqrt(mc),
|
||||
"near 10 rounding half even");
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Probe for rounding failures near a power of ten, 1 = 10^0,
|
||||
* where an ulp has a different size above and below the value.
|
||||
*/
|
||||
private static int nearOne() {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal near1 = new BigDecimal(".999999999999999999999");
|
||||
BigDecimal near1sq = near1.multiply(near1);
|
||||
BigDecimal near1sq_ulp = near1sq.add(near1sq.ulp());
|
||||
|
||||
for (int i = 10; i < 23; i++) {
|
||||
for (RoundingMode rm : List.of(RoundingMode.HALF_EVEN,
|
||||
RoundingMode.UP,
|
||||
RoundingMode.DOWN )) {
|
||||
MathContext mc = new MathContext(i, rm);
|
||||
failures += equalNumerically(BigSquareRoot.sqrt(near1sq_ulp, mc),
|
||||
near1sq_ulp.sqrt(mc),
|
||||
mc.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
|
||||
private static int halfWay() {
|
||||
int failures = 0;
|
||||
|
||||
/*
|
||||
* Use enough digits that the exact result cannot be computed
|
||||
* from the sqrt of a double.
|
||||
*/
|
||||
BigDecimal[] halfWayCases = {
|
||||
// Odd next digit, truncate on HALF_EVEN
|
||||
new BigDecimal("123456789123456789.5"),
|
||||
|
||||
// Even next digit, round up on HALF_EVEN
|
||||
new BigDecimal("123456789123456788.5"),
|
||||
};
|
||||
|
||||
for (BigDecimal halfWayCase : halfWayCases) {
|
||||
// Round result to next-to-last place
|
||||
int precision = halfWayCase.precision() - 1;
|
||||
BigDecimal square = halfWayCase.multiply(halfWayCase);
|
||||
|
||||
for (RoundingMode rm : List.of(RoundingMode.HALF_EVEN,
|
||||
RoundingMode.HALF_UP,
|
||||
RoundingMode.HALF_DOWN)) {
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
|
||||
System.out.println("\nRounding mode " + rm);
|
||||
System.out.println("\t" + halfWayCase.round(mc) + "\t" + halfWayCase);
|
||||
System.out.println("\t" + BigSquareRoot.sqrt(square, mc));
|
||||
|
||||
failures += equalNumerically(/*square.sqrt(mc),*/
|
||||
BigSquareRoot.sqrt(square, mc),
|
||||
halfWayCase.round(mc),
|
||||
"Rounding halway " + rm);
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int compare(BigDecimal a, BigDecimal b, boolean expected, String prefix) {
|
||||
boolean result = a.equals(b);
|
||||
int failed = (result==expected) ? 0 : 1;
|
||||
if (failed == 1) {
|
||||
System.err.println("Testing " + prefix +
|
||||
"(" + a + ").compareTo(" + b + ") => " + result +
|
||||
"\n\tExpected " + expected);
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
private static int equalNumerically(BigDecimal a, BigDecimal b,
|
||||
String prefix) {
|
||||
return compareNumerically(a, b, 0, prefix);
|
||||
}
|
||||
|
||||
|
||||
private static int compareNumerically(BigDecimal a, BigDecimal b,
|
||||
int expected, String prefix) {
|
||||
int result = a.compareTo(b);
|
||||
int failed = (result==expected) ? 0 : 1;
|
||||
if (failed == 1) {
|
||||
System.err.println("Testing " + prefix +
|
||||
"(" + a + ").compareTo(" + b + ") => " + result +
|
||||
"\n\tExpected " + expected);
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative implementation of BigDecimal square root which uses
|
||||
* higher-precision for a simpler set of termination conditions
|
||||
* for the Newton iteration.
|
||||
*/
|
||||
private static class BigSquareRoot {
|
||||
|
||||
/**
|
||||
* The value 0.5, with a scale of 1.
|
||||
*/
|
||||
private static final BigDecimal ONE_HALF = valueOf(5L, 1);
|
||||
|
||||
public static boolean isPowerOfTen(BigDecimal bd) {
|
||||
return BigInteger.ONE.equals(bd.unscaledValue());
|
||||
}
|
||||
|
||||
public static BigDecimal square(BigDecimal bd) {
|
||||
return bd.multiply(bd);
|
||||
}
|
||||
|
||||
public static BigDecimal sqrt(BigDecimal bd, MathContext mc) {
|
||||
int signum = bd.signum();
|
||||
if (signum == 1) {
|
||||
/*
|
||||
* The following code draws on the algorithm presented in
|
||||
* "Properly Rounded Variable Precision Square Root," Hull and
|
||||
* Abrham, ACM Transactions on Mathematical Software, Vol 11,
|
||||
* No. 3, September 1985, Pages 229-237.
|
||||
*
|
||||
* The BigDecimal computational model differs from the one
|
||||
* presented in the paper in several ways: first BigDecimal
|
||||
* numbers aren't necessarily normalized, second many more
|
||||
* rounding modes are supported, including UNNECESSARY, and
|
||||
* exact results can be requested.
|
||||
*
|
||||
* The main steps of the algorithm below are as follows,
|
||||
* first argument reduce the value to the numerical range
|
||||
* [1, 10) using the following relations:
|
||||
*
|
||||
* x = y * 10 ^ exp
|
||||
* sqrt(x) = sqrt(y) * 10^(exp / 2) if exp is even
|
||||
* sqrt(x) = sqrt(y/10) * 10 ^((exp+1)/2) is exp is odd
|
||||
*
|
||||
* Then use Newton's iteration on the reduced value to compute
|
||||
* the numerical digits of the desired result.
|
||||
*
|
||||
* Finally, scale back to the desired exponent range and
|
||||
* perform any adjustment to get the preferred scale in the
|
||||
* representation.
|
||||
*/
|
||||
|
||||
// The code below favors relative simplicity over checking
|
||||
// for special cases that could run faster.
|
||||
|
||||
int preferredScale = Math.ceilDiv(bd.scale(), 2);
|
||||
|
||||
BigDecimal zeroWithFinalPreferredScale =
|
||||
BigDecimal.valueOf(0L, preferredScale);
|
||||
|
||||
// First phase of numerical normalization, strip trailing
|
||||
// zeros and check for even powers of 10.
|
||||
BigDecimal stripped = bd.stripTrailingZeros();
|
||||
int strippedScale = stripped.scale();
|
||||
|
||||
// Numerically sqrt(10^2N) = 10^N
|
||||
if (isPowerOfTen(stripped) &&
|
||||
strippedScale % 2 == 0) {
|
||||
BigDecimal result = BigDecimal.valueOf(1L, strippedScale/2);
|
||||
if (result.scale() != preferredScale) {
|
||||
// Adjust to requested precision and preferred
|
||||
// scale as appropriate.
|
||||
result = result.add(zeroWithFinalPreferredScale, mc);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// After stripTrailingZeros, the representation is normalized as
|
||||
//
|
||||
// unscaledValue * 10^(-scale)
|
||||
//
|
||||
// where unscaledValue is an integer with the mimimum
|
||||
// precision for the cohort of the numerical value. To
|
||||
// allow binary floating-point hardware to be used to get
|
||||
// approximately a 15 digit approximation to the square
|
||||
// root, it is helpful to instead normalize this so that
|
||||
// the significand portion is to right of the decimal
|
||||
// point by roughly (scale() - precision() + 1).
|
||||
|
||||
// Now the precision / scale adjustment
|
||||
int scaleAdjust = 0;
|
||||
int scale = stripped.scale() - stripped.precision() + 1;
|
||||
if (scale % 2 == 0) {
|
||||
scaleAdjust = scale;
|
||||
} else {
|
||||
scaleAdjust = scale - 1;
|
||||
}
|
||||
|
||||
BigDecimal working = stripped.scaleByPowerOfTen(scaleAdjust);
|
||||
|
||||
assert // Verify 0.1 <= working < 10
|
||||
ONE_TENTH.compareTo(working) <= 0 && working.compareTo(TEN) < 0;
|
||||
|
||||
// Use good ole' Math.sqrt to get the initial guess for
|
||||
// the Newton iteration, good to at least 15 decimal
|
||||
// digits. This approach does incur the cost of a
|
||||
//
|
||||
// BigDecimal -> double -> BigDecimal
|
||||
//
|
||||
// conversion cycle, but it avoids the need for several
|
||||
// Newton iterations in BigDecimal arithmetic to get the
|
||||
// working answer to 15 digits of precision. If many fewer
|
||||
// than 15 digits were needed, it might be faster to do
|
||||
// the loop entirely in BigDecimal arithmetic.
|
||||
//
|
||||
// (A double value might have as much many as 17 decimal
|
||||
// digits of precision; it depends on the relative density
|
||||
// of binary and decimal numbers at different regions of
|
||||
// the number line.)
|
||||
//
|
||||
// (It would be possible to check for certain special
|
||||
// cases to avoid doing any Newton iterations. For
|
||||
// example, if the BigDecimal -> double conversion was
|
||||
// known to be exact and the rounding mode had a
|
||||
// low-enough precision, the post-Newton rounding logic
|
||||
// could be applied directly.)
|
||||
|
||||
BigDecimal guess = new BigDecimal(Math.sqrt(working.doubleValue()));
|
||||
int guessPrecision = 15;
|
||||
int originalPrecision = mc.getPrecision();
|
||||
int targetPrecision;
|
||||
|
||||
// If an exact value is requested, it must only need
|
||||
// about half of the input digits to represent since
|
||||
// multiplying an N digit number by itself yield a (2N
|
||||
// - 1) digit or 2N digit result.
|
||||
if (originalPrecision == 0) {
|
||||
targetPrecision = stripped.precision()/2 + 1;
|
||||
} else {
|
||||
targetPrecision = originalPrecision;
|
||||
}
|
||||
|
||||
// When setting the precision to use inside the Newton
|
||||
// iteration loop, take care to avoid the case where the
|
||||
// precision of the input exceeds the requested precision
|
||||
// and rounding the input value too soon.
|
||||
BigDecimal approx = guess;
|
||||
int workingPrecision = working.precision();
|
||||
// Use "2p + 2" property to guarantee enough
|
||||
// intermediate precision so that a double-rounding
|
||||
// error does not occur when rounded to the final
|
||||
// destination precision.
|
||||
int loopPrecision =
|
||||
Math.max(2 * Math.max(targetPrecision, workingPrecision) + 2,
|
||||
34); // Force at least two Netwon
|
||||
// iterations on the Math.sqrt
|
||||
// result.
|
||||
do {
|
||||
MathContext mcTmp = new MathContext(loopPrecision, RoundingMode.HALF_EVEN);
|
||||
// approx = 0.5 * (approx + fraction / approx)
|
||||
approx = ONE_HALF.multiply(approx.add(working.divide(approx, mcTmp), mcTmp));
|
||||
guessPrecision *= 2;
|
||||
} while (guessPrecision < loopPrecision);
|
||||
|
||||
BigDecimal result;
|
||||
RoundingMode targetRm = mc.getRoundingMode();
|
||||
if (targetRm == RoundingMode.UNNECESSARY || originalPrecision == 0) {
|
||||
RoundingMode tmpRm =
|
||||
(targetRm == RoundingMode.UNNECESSARY) ? RoundingMode.DOWN : targetRm;
|
||||
MathContext mcTmp = new MathContext(targetPrecision, tmpRm);
|
||||
result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mcTmp);
|
||||
|
||||
// If result*result != this numerically, the square
|
||||
// root isn't exact
|
||||
if (bd.subtract(square(result)).compareTo(ZERO) != 0) {
|
||||
throw new ArithmeticException("Computed square root not exact.");
|
||||
}
|
||||
} else {
|
||||
result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mc);
|
||||
}
|
||||
|
||||
assert squareRootResultAssertions(bd, result, mc);
|
||||
if (result.scale() != preferredScale) {
|
||||
// The preferred scale of an add is
|
||||
// max(addend.scale(), augend.scale()). Therefore, if
|
||||
// the scale of the result is first minimized using
|
||||
// stripTrailingZeros(), adding a zero of the
|
||||
// preferred scale rounding the correct precision will
|
||||
// perform the proper scale vs precision tradeoffs.
|
||||
result = result.stripTrailingZeros().
|
||||
add(zeroWithFinalPreferredScale,
|
||||
new MathContext(originalPrecision, RoundingMode.UNNECESSARY));
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
switch (signum) {
|
||||
case -1:
|
||||
throw new ArithmeticException("Attempted square root " +
|
||||
"of negative BigDecimal");
|
||||
case 0:
|
||||
return valueOf(0L, bd.scale()/2);
|
||||
|
||||
default:
|
||||
throw new AssertionError("Bad value from signum");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For nonzero values, check numerical correctness properties of
|
||||
* the computed result for the chosen rounding mode.
|
||||
*
|
||||
* For the directed roundings, for DOWN and FLOOR, result^2 must
|
||||
* be {@code <=} the input and (result+ulp)^2 must be {@code >} the
|
||||
* input. Conversely, for UP and CEIL, result^2 must be {@code >=} the
|
||||
* input and (result-ulp)^2 must be {@code <} the input.
|
||||
*/
|
||||
private static boolean squareRootResultAssertions(BigDecimal input, BigDecimal result, MathContext mc) {
|
||||
if (result.signum() == 0) {
|
||||
return squareRootZeroResultAssertions(input, result, mc);
|
||||
} else {
|
||||
RoundingMode rm = mc.getRoundingMode();
|
||||
BigDecimal ulp = result.ulp();
|
||||
BigDecimal neighborUp = result.add(ulp);
|
||||
// Make neighbor down accurate even for powers of ten
|
||||
if (isPowerOfTen(result)) {
|
||||
ulp = ulp.divide(TEN);
|
||||
}
|
||||
BigDecimal neighborDown = result.subtract(ulp);
|
||||
|
||||
// Both the starting value and result should be nonzero and positive.
|
||||
if (result.signum() != 1 ||
|
||||
input.signum() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (rm) {
|
||||
case DOWN:
|
||||
case FLOOR:
|
||||
assert
|
||||
square(result).compareTo(input) <= 0 &&
|
||||
square(neighborUp).compareTo(input) > 0:
|
||||
"Square of result out for bounds rounding " + rm;
|
||||
return true;
|
||||
|
||||
case UP:
|
||||
case CEILING:
|
||||
assert
|
||||
square(result).compareTo(input) >= 0 :
|
||||
"Square of result too small rounding " + rm;
|
||||
|
||||
assert
|
||||
square(neighborDown).compareTo(input) < 0 :
|
||||
"Square of down neighbor too large rounding " + rm + "\n" +
|
||||
"\t input: " + input + "\t neighborDown: " + neighborDown +"\t sqrt: " + result +
|
||||
"\t" + mc;
|
||||
return true;
|
||||
|
||||
|
||||
case HALF_DOWN:
|
||||
case HALF_EVEN:
|
||||
case HALF_UP:
|
||||
BigDecimal err = square(result).subtract(input).abs();
|
||||
BigDecimal errUp = square(neighborUp).subtract(input);
|
||||
BigDecimal errDown = input.subtract(square(neighborDown));
|
||||
// All error values should be positive so don't need to
|
||||
// compare absolute values.
|
||||
|
||||
int err_comp_errUp = err.compareTo(errUp);
|
||||
int err_comp_errDown = err.compareTo(errDown);
|
||||
|
||||
assert
|
||||
errUp.signum() == 1 &&
|
||||
errDown.signum() == 1 :
|
||||
"Errors of neighbors squared don't have correct signs";
|
||||
|
||||
// At least one of these must be true, but not both
|
||||
// assert
|
||||
// err_comp_errUp <= 0 : "Upper neighbor is closer than result: " + rm +
|
||||
// "\t" + input + "\t result" + result;
|
||||
// assert
|
||||
// err_comp_errDown <= 0 : "Lower neighbor is closer than result: " + rm +
|
||||
// "\t" + input + "\t result " + result + "\t lower neighbor: " + neighborDown;
|
||||
|
||||
assert
|
||||
((err_comp_errUp == 0 ) ? err_comp_errDown < 0 : true) &&
|
||||
((err_comp_errDown == 0 ) ? err_comp_errUp < 0 : true) :
|
||||
"Incorrect error relationships";
|
||||
// && could check for digit conditions for ties too
|
||||
return true;
|
||||
|
||||
default: // Definition of UNNECESSARY already verified.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean squareRootZeroResultAssertions(BigDecimal input,
|
||||
BigDecimal result,
|
||||
MathContext mc) {
|
||||
return input.compareTo(ZERO) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
185
test/jdk/java/math/BigDecimal/StringConstructor.java
Normal file
185
test/jdk/java/math/BigDecimal/StringConstructor.java
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.RandomFactory
|
||||
* @run main StringConstructor
|
||||
* @bug 4103117 4331084 4488017 4490929 6255285 6268365 8074460 8078672 8233760
|
||||
* @summary Tests the BigDecimal string constructor (use -Dseed=X to set PRNG seed).
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import java.util.Random;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
|
||||
public class StringConstructor {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
constructWithError("");
|
||||
constructWithError("+");
|
||||
constructWithError("-");
|
||||
constructWithError("+e");
|
||||
constructWithError("-e");
|
||||
constructWithError("e+");
|
||||
constructWithError("1.-0");
|
||||
constructWithError(".-123");
|
||||
constructWithError("-");
|
||||
constructWithError("--1.1");
|
||||
constructWithError("-+1.1");
|
||||
constructWithError("+-1.1");
|
||||
constructWithError("1-.1");
|
||||
constructWithError("1+.1");
|
||||
constructWithError("1.111+1");
|
||||
constructWithError("1.111-1");
|
||||
constructWithError("11.e+");
|
||||
constructWithError("11.e-");
|
||||
constructWithError("11.e+-");
|
||||
constructWithError("11.e-+");
|
||||
constructWithError("11.e-+1");
|
||||
constructWithError("11.e+-1");
|
||||
|
||||
// Range checks
|
||||
constructWithError("1e"+Integer.MIN_VALUE);
|
||||
constructWithError("10e"+Integer.MIN_VALUE);
|
||||
constructWithError("0.01e"+Integer.MIN_VALUE);
|
||||
constructWithError("1e"+((long)Integer.MIN_VALUE-1));
|
||||
|
||||
leadingExponentZeroTest();
|
||||
nonAsciiZeroTest();
|
||||
|
||||
/* These BigDecimals produce a string with an exponent > Integer.MAX_VALUE */
|
||||
roundtripWithAbnormalExponent(BigDecimal.valueOf(10, Integer.MIN_VALUE));
|
||||
roundtripWithAbnormalExponent(BigDecimal.valueOf(Long.MIN_VALUE, Integer.MIN_VALUE));
|
||||
roundtripWithAbnormalExponent(new BigDecimal(new BigInteger("1" + "0".repeat(100)), Integer.MIN_VALUE));
|
||||
|
||||
/* These Strings have an exponent > Integer.MAX_VALUE */
|
||||
roundtripWithAbnormalExponent("1.0E+2147483649");
|
||||
roundtripWithAbnormalExponent("-9.223372036854775808E+2147483666");
|
||||
roundtripWithAbnormalExponent("1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E+2147483748");
|
||||
|
||||
// Roundtrip tests
|
||||
Random random = RandomFactory.getRandom();
|
||||
for (int i=0; i<100; i++) {
|
||||
int size = random.nextInt(100) + 1;
|
||||
BigInteger bi = new BigInteger(size, random);
|
||||
if (random.nextBoolean())
|
||||
bi = bi.negate();
|
||||
int decimalLength = bi.toString().length();
|
||||
int scale = random.nextInt(decimalLength);
|
||||
BigDecimal bd = new BigDecimal(bi, scale);
|
||||
String bdString = bd.toString();
|
||||
// System.err.println("bi" + bi.toString() + "\tscale " + scale);
|
||||
// System.err.println("bd string: " + bdString);
|
||||
BigDecimal bdDoppel = new BigDecimal(bdString);
|
||||
if (!bd.equals(bdDoppel)) {
|
||||
System.err.println("bd string: scale: " + bd.scale() +
|
||||
"\t" + bdString);
|
||||
System.err.println("bd doppel: scale: " + bdDoppel.scale() +
|
||||
"\t" + bdDoppel.toString());
|
||||
throw new RuntimeException("String constructor failure.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void roundtripWithAbnormalExponent(BigDecimal bd) {
|
||||
if (!bd.equals(new BigDecimal(bd.toString()))) {
|
||||
throw new RuntimeException("Abnormal exponent roundtrip failure");
|
||||
}
|
||||
}
|
||||
|
||||
private static void roundtripWithAbnormalExponent(String s) {
|
||||
if (!s.equals(new BigDecimal(s).toString())) {
|
||||
throw new RuntimeException("Abnormal exponent roundtrip failure");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify precision is set properly if the significand has
|
||||
* non-ASCII leading zeros.
|
||||
*/
|
||||
private static void nonAsciiZeroTest() {
|
||||
String values[] = {
|
||||
"00004e5",
|
||||
"\u0660\u0660\u0660\u06604e5",
|
||||
};
|
||||
|
||||
BigDecimal expected = new BigDecimal("4e5");
|
||||
|
||||
for(String s : values) {
|
||||
BigDecimal tmp = new BigDecimal(s);
|
||||
// System.err.println("Testing " + s);
|
||||
if (! expected.equals(tmp) || tmp.precision() != 1) {
|
||||
System.err.println("Bad conversion of " + s + "got " +
|
||||
tmp + "precision = " + tmp.precision());
|
||||
throw new RuntimeException("String constructor failure.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void leadingExponentZeroTest() {
|
||||
BigDecimal twelve = new BigDecimal("12");
|
||||
BigDecimal onePointTwo = new BigDecimal("1.2");
|
||||
|
||||
String start = "1.2e0";
|
||||
String end = "1";
|
||||
String middle = "";
|
||||
|
||||
// Test with more excess zeros than the largest number of
|
||||
// decimal digits needed to represent a long
|
||||
int limit = ((int)Math.log10(Long.MAX_VALUE)) + 6;
|
||||
for(int i = 0; i < limit; i++, middle += "0") {
|
||||
String t1 = start + middle;
|
||||
String t2 = t1 + end;
|
||||
|
||||
// System.out.println(i + "\t" + t1 + "\t" + t2);
|
||||
testString(t1, onePointTwo);
|
||||
testString(t2, twelve);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testString(String s, BigDecimal expected) {
|
||||
testString0(s, expected);
|
||||
testString0(switchZero(s), expected);
|
||||
}
|
||||
|
||||
private static void testString0(String s, BigDecimal expected) {
|
||||
if (!expected.equals(new BigDecimal(s)))
|
||||
throw new RuntimeException(s + " is not equal to " + expected);
|
||||
}
|
||||
|
||||
private static String switchZero(String s) {
|
||||
return s.replace('0', '\u0660'); // Arabic-Indic zero
|
||||
}
|
||||
|
||||
private static void constructWithError(String badString) {
|
||||
try {
|
||||
BigDecimal d = new BigDecimal(badString);
|
||||
throw new RuntimeException(badString + " accepted");
|
||||
} catch(NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
94
test/jdk/java/math/BigDecimal/StrippingZerosTest.java
Normal file
94
test/jdk/java/math/BigDecimal/StrippingZerosTest.java
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4108852
|
||||
* @summary A few tests of stripTrailingZeros
|
||||
* @run main StrippingZerosTest
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox -XX:AutoBoxCacheMax=20000 StrippingZerosTest
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
|
||||
public class StrippingZerosTest {
|
||||
public static void main(String argv[]) {
|
||||
BigDecimal [][] testCases = {
|
||||
{new BigDecimal("1.00000"), new BigDecimal("1")},
|
||||
{new BigDecimal("1.000"), new BigDecimal("1")},
|
||||
{new BigDecimal("1"), new BigDecimal("1")},
|
||||
{new BigDecimal("0.1234"), new BigDecimal("0.1234")},
|
||||
{new BigDecimal("0.12340"), new BigDecimal("0.1234")},
|
||||
{new BigDecimal("0.12340000000"), new BigDecimal("0.1234")},
|
||||
{new BigDecimal("1234.5678"), new BigDecimal("1234.5678")},
|
||||
{new BigDecimal("1234.56780"), new BigDecimal("1234.5678")},
|
||||
{new BigDecimal("1234.567800000"), new BigDecimal("1234.5678")},
|
||||
{new BigDecimal("0"), new BigDecimal("0")},
|
||||
{new BigDecimal("0e2"), BigDecimal.ZERO},
|
||||
{new BigDecimal("0e-2"), BigDecimal.ZERO},
|
||||
{new BigDecimal("0e42"), BigDecimal.ZERO},
|
||||
{new BigDecimal("+0e42"), BigDecimal.ZERO},
|
||||
{new BigDecimal("-0e42"), BigDecimal.ZERO},
|
||||
{new BigDecimal("0e-42"), BigDecimal.ZERO},
|
||||
{new BigDecimal("+0e-42"), BigDecimal.ZERO},
|
||||
{new BigDecimal("-0e-42"), BigDecimal.ZERO},
|
||||
{new BigDecimal("0e-2"), BigDecimal.ZERO},
|
||||
{new BigDecimal("0e100"), BigDecimal.ZERO},
|
||||
{new BigDecimal("0e-100"), BigDecimal.ZERO},
|
||||
{new BigDecimal("10"), new BigDecimal("1e1")},
|
||||
{new BigDecimal("20"), new BigDecimal("2e1")},
|
||||
{new BigDecimal("100"), new BigDecimal("1e2")},
|
||||
{new BigDecimal("1000000000"), new BigDecimal("1e9")},
|
||||
{new BigDecimal("100000000e1"), new BigDecimal("1e9")},
|
||||
{new BigDecimal("10000000e2"), new BigDecimal("1e9")},
|
||||
{new BigDecimal("1000000e3"), new BigDecimal("1e9")},
|
||||
{new BigDecimal("100000e4"), new BigDecimal("1e9")},
|
||||
// BD value which larger than Long.MaxValue
|
||||
{new BigDecimal("1.0000000000000000000000000000"), new BigDecimal("1")},
|
||||
{new BigDecimal("-1.0000000000000000000000000000"), new BigDecimal("-1")},
|
||||
{new BigDecimal("1.00000000000000000000000000001"), new BigDecimal("1.00000000000000000000000000001")},
|
||||
{new BigDecimal("1000000000000000000000000000000e4"), new BigDecimal("1e34")},
|
||||
};
|
||||
|
||||
for(int i = 0; i < testCases.length; i++) {
|
||||
|
||||
if (!(testCases[i][0]).stripTrailingZeros().equals(testCases[i][1])) {
|
||||
throw new RuntimeException("For input " + testCases[i][0].toString() +
|
||||
" did not received expected result " +
|
||||
testCases[i][1].toString() + ", got " +
|
||||
testCases[i][0].stripTrailingZeros());
|
||||
}
|
||||
|
||||
testCases[i][0] = testCases[i][0].negate();
|
||||
testCases[i][1] = testCases[i][1].negate();
|
||||
|
||||
if (!(testCases[i][0]).stripTrailingZeros().equals(testCases[i][1])) {
|
||||
throw new RuntimeException("For input " + testCases[i][0].toString() +
|
||||
" did not received expected result " +
|
||||
testCases[i][1].toString() + ", got " +
|
||||
testCases[i][0].stripTrailingZeros());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
131
test/jdk/java/math/BigDecimal/ToPlainStringTests.java
Normal file
131
test/jdk/java/math/BigDecimal/ToPlainStringTests.java
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4984872 8318915
|
||||
* @summary Basic tests of toPlainString method
|
||||
* @run main ToPlainStringTests
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox -XX:AutoBoxCacheMax=20000 ToPlainStringTests
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
|
||||
public class ToPlainStringTests {
|
||||
public static void main(String argv[]) {
|
||||
String [][] testCases = {
|
||||
{"0", "0"},
|
||||
{"1", "1"},
|
||||
{"10", "10"},
|
||||
{"2e1", "20"},
|
||||
{"3e2", "300"},
|
||||
{"4e3", "4000"},
|
||||
{"5e4", "50000"},
|
||||
{"6e5", "600000"},
|
||||
{"7e6", "7000000"},
|
||||
{"8e7", "80000000"},
|
||||
{"9e8", "900000000"},
|
||||
{"1e9", "1000000000"},
|
||||
|
||||
{".0", "0.0"},
|
||||
{".1", "0.1"},
|
||||
{".10", "0.10"},
|
||||
{"1e-1", "0.1"},
|
||||
{"1e-1", "0.1"},
|
||||
{"2e-2", "0.02"},
|
||||
{"3e-3", "0.003"},
|
||||
{"4e-4", "0.0004"},
|
||||
{"5e-5", "0.00005"},
|
||||
{"6e-6", "0.000006"},
|
||||
{"7e-7", "0.0000007"},
|
||||
{"8e-8", "0.00000008"},
|
||||
{"9e-9", "0.000000009"},
|
||||
{"9000e-12", "0.000000009000"},
|
||||
|
||||
{"9000e-22", "0.0000000000000000009000"},
|
||||
{"12345678901234567890", "12345678901234567890"},
|
||||
{"12345678901234567890e22", "123456789012345678900000000000000000000000"},
|
||||
{"12345678901234567890e-22", "0.0012345678901234567890"},
|
||||
|
||||
{"12345e-1", "1234.5"},
|
||||
{"12345e-2", "123.45"},
|
||||
{"12345e-3", "12.345"},
|
||||
{"12345e-4", "1.2345"},
|
||||
};
|
||||
|
||||
int errors = 0;
|
||||
for(String[] testCase: testCases) {
|
||||
BigDecimal bd = new BigDecimal(testCase[0]);
|
||||
String s;
|
||||
|
||||
if (!(s=bd.toPlainString()).equals(testCase[1])) {
|
||||
errors++;
|
||||
System.err.println("Unexpected plain result ``" +
|
||||
s + "'' from BigDecimal " +
|
||||
bd);
|
||||
}
|
||||
bd = new BigDecimal("-"+testCase[0]);
|
||||
if (bd.signum()!=0 && !(s=(bd.toPlainString())).equals("-"+testCase[1])) {
|
||||
errors++;
|
||||
System.err.println("Unexpected plain result ``" +
|
||||
s + "'' from BigDecimal " +
|
||||
bd);
|
||||
}
|
||||
}
|
||||
|
||||
String[] failingCases = {
|
||||
"1E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 2 chars
|
||||
"1E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 1 chars
|
||||
|
||||
"-1E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 3 chars
|
||||
"-1E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 2 chars
|
||||
"-1E-" + (Integer.MAX_VALUE - 2), // MAX_VALUE + 1 chars
|
||||
|
||||
"123456789E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 2 chars
|
||||
"123456789E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 1 chars
|
||||
|
||||
"-123456789E-" + (Integer.MAX_VALUE - 0), // MAX_VALUE + 3 chars
|
||||
"-123456789E-" + (Integer.MAX_VALUE - 1), // MAX_VALUE + 2 chars
|
||||
"-123456789E-" + (Integer.MAX_VALUE - 2), // MAX_VALUE + 1 chars
|
||||
|
||||
"1E" + Integer.MAX_VALUE, // MAX_VALUE + 1 chars
|
||||
"123456789E" + Integer.MAX_VALUE, // MAX_VALUE + 9 chars
|
||||
|
||||
"-1E" + Integer.MAX_VALUE, // MAX_VALUE + 2 chars
|
||||
"-123456789E" + Integer.MAX_VALUE, // MAX_VALUE + 10 chars
|
||||
};
|
||||
/* We expect pre-emptive OutOfMemoryErrors, nothing else */
|
||||
for (String failingCase : failingCases) {
|
||||
try {
|
||||
new BigDecimal(failingCase).toPlainString();
|
||||
} catch (OutOfMemoryError expected) {
|
||||
continue;
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
++errors;
|
||||
}
|
||||
|
||||
if(errors > 0)
|
||||
throw new RuntimeException(errors + " errors during run.");
|
||||
}
|
||||
}
|
||||
74
test/jdk/java/math/BigDecimal/ValueOfDouble.java
Normal file
74
test/jdk/java/math/BigDecimal/ValueOfDouble.java
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8356709
|
||||
* @summary Test Double.toString(double)
|
||||
* @run junit ValueOfDouble
|
||||
*/
|
||||
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
|
||||
public class ValueOfDouble {
|
||||
private static final String DIGITS = "1234567000003456789"; // Enough digits to fill a long
|
||||
|
||||
@Test
|
||||
public void testValueOfDouble() {
|
||||
checkValue(0.0);
|
||||
checkValue(-0.0);
|
||||
checkValue(Math.PI);
|
||||
checkValue(-Math.PI);
|
||||
checkValue(Double.MAX_VALUE);
|
||||
checkValue(Double.MIN_VALUE);
|
||||
checkValue(1e-44); // Lots of digits with lots of 9s
|
||||
|
||||
for (int prec = 1; prec < DIGITS.length(); prec++) {
|
||||
String prefix = DIGITS.substring(0, prec);
|
||||
for (int exp = -30; exp < 30; exp++) {
|
||||
double value = Double.parseDouble(prefix + "e" + exp);
|
||||
checkValue(value);
|
||||
checkValue(-value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkValue(double value) {
|
||||
BigDecimal expected = new BigDecimal(Double.toString(value));
|
||||
assertEquals(expected, BigDecimal.valueOf(value));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptions() {
|
||||
assertThrows(NumberFormatException.class, () -> BigDecimal.valueOf(Double.NaN));
|
||||
assertThrows(NumberFormatException.class, () -> BigDecimal.valueOf(Double.POSITIVE_INFINITY));
|
||||
assertThrows(NumberFormatException.class, () -> BigDecimal.valueOf(Double.NEGATIVE_INFINITY));
|
||||
}
|
||||
}
|
||||
476
test/jdk/java/math/BigDecimal/ZeroScalingTests.java
Normal file
476
test/jdk/java/math/BigDecimal/ZeroScalingTests.java
Normal file
|
|
@ -0,0 +1,476 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4902952 4905407 4916149 8057793
|
||||
* @summary Tests that the scale of zero is propagated properly and has the
|
||||
* proper effect and that setting the scale to zero does not mutate the
|
||||
* BigDecimal.
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ZeroScalingTests {
|
||||
|
||||
static MathContext longEnough = new MathContext(50, RoundingMode.UNNECESSARY);
|
||||
|
||||
static BigDecimal[] zeros = new BigDecimal[23];
|
||||
static {
|
||||
for(int i = 0; i < 21; i++) {
|
||||
zeros[i] = new BigDecimal(BigInteger.ZERO, i-10);
|
||||
}
|
||||
zeros[21] = new BigDecimal(BigInteger.ZERO, Integer.MIN_VALUE);
|
||||
zeros[22] = new BigDecimal(BigInteger.ZERO, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
static BigDecimal element = BigDecimal.valueOf(100, -2);
|
||||
|
||||
static MathContext contexts[] = {
|
||||
new MathContext(0, RoundingMode.UNNECESSARY),
|
||||
new MathContext(100, RoundingMode.UNNECESSARY),
|
||||
new MathContext(5, RoundingMode.UNNECESSARY),
|
||||
new MathContext(4, RoundingMode.UNNECESSARY),
|
||||
new MathContext(3, RoundingMode.UNNECESSARY),
|
||||
new MathContext(2, RoundingMode.UNNECESSARY),
|
||||
new MathContext(1, RoundingMode.UNNECESSARY),
|
||||
};
|
||||
|
||||
|
||||
static int addTests() {
|
||||
int failures = 0;
|
||||
|
||||
for(BigDecimal zero1: zeros) {
|
||||
for(BigDecimal zero2: zeros) {
|
||||
BigDecimal expected = new BigDecimal(BigInteger.ZERO,
|
||||
Math.max(zero1.scale(), zero2.scale()));
|
||||
BigDecimal result;
|
||||
|
||||
if(! (result=zero1.add(zero2)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For classic exact add, expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
if(! (result=zero1.add(zero2, MathContext.UNLIMITED)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For UNLIMITED math context add," +
|
||||
" expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
if(! (result=zero1.add(zero2, longEnough)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For longEnough math context add," +
|
||||
" expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Test effect of adding zero to a nonzero value.
|
||||
for (MathContext mc: contexts) {
|
||||
for (BigDecimal zero: zeros) {
|
||||
if (Math.abs((long)zero.scale()) < 100 ) {
|
||||
|
||||
int preferredScale = Math.max(zero.scale(), element.scale());
|
||||
if (mc.getPrecision() != 0) {
|
||||
if (preferredScale < -4 )
|
||||
preferredScale = -4;
|
||||
else if (preferredScale > -(5 - mc.getPrecision())) {
|
||||
preferredScale = -(5 - mc.getPrecision());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
System.err.println("\n " + element + " +\t" + zero + " =\t" + result);
|
||||
|
||||
System.err.println("scales" + element.scale() + " \t" + zero.scale() +
|
||||
" \t " + result.scale() + "\t precison = " + mc.getPrecision());
|
||||
System.err.println("expected scale = " + preferredScale);
|
||||
*/
|
||||
|
||||
BigDecimal result = element.add(zero, mc);
|
||||
if (result.scale() != preferredScale ||
|
||||
result.compareTo(element) != 0) {
|
||||
failures++;
|
||||
System.err.println("Expected scale " + preferredScale +
|
||||
" result scale was " + result.scale() +
|
||||
" ; value was " + result);
|
||||
}
|
||||
|
||||
result = zero.add(element, mc);
|
||||
if (result.scale() != preferredScale ||
|
||||
result.compareTo(element) != 0) {
|
||||
failures++;
|
||||
System.err.println("Expected scale " + preferredScale +
|
||||
" result scale was " + result.scale() +
|
||||
" ; value was " + result);
|
||||
}
|
||||
|
||||
result = element.negate().add(zero, mc);
|
||||
if (result.scale() != preferredScale ||
|
||||
result.compareTo(element.negate()) != 0) {
|
||||
failures++;
|
||||
System.err.println("Expected scale " + preferredScale +
|
||||
" result scale was " + result.scale() +
|
||||
" ; value was " + result);
|
||||
}
|
||||
|
||||
result = zero.add(element.negate(), mc);
|
||||
if (result.scale() != preferredScale ||
|
||||
result.compareTo(element.negate()) != 0) {
|
||||
failures++;
|
||||
System.err.println("Expected scale " + preferredScale +
|
||||
" result scale was " + result.scale() +
|
||||
" ; value was " + result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int subtractTests() {
|
||||
int failures = 0;
|
||||
|
||||
for(BigDecimal zero1: zeros) {
|
||||
for(BigDecimal zero2: zeros) {
|
||||
BigDecimal expected = new BigDecimal(BigInteger.ZERO,
|
||||
Math.max(zero1.scale(), zero2.scale()));
|
||||
BigDecimal result;
|
||||
|
||||
if(! (result=zero1.subtract(zero2)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For classic exact subtract, expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
if(! (result=zero1.subtract(zero2, MathContext.UNLIMITED)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For UNLIMITED math context subtract," +
|
||||
" expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
if(! (result=zero1.subtract(zero2, longEnough)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For longEnough math context subtract," +
|
||||
" expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test effect of adding zero to a nonzero value.
|
||||
for (MathContext mc: contexts) {
|
||||
for (BigDecimal zero: zeros) {
|
||||
if (Math.abs((long)zero.scale()) < 100 ) {
|
||||
|
||||
int preferredScale = Math.max(zero.scale(), element.scale());
|
||||
if (mc.getPrecision() != 0) {
|
||||
if (preferredScale < -4 )
|
||||
preferredScale = -4;
|
||||
else if (preferredScale > -(5 - mc.getPrecision())) {
|
||||
preferredScale = -(5 - mc.getPrecision());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
System.err.println("\n " + element + " +\t" + zero + " =\t" + result);
|
||||
|
||||
System.err.println("scales" + element.scale() + " \t" + zero.scale() +
|
||||
" \t " + result.scale() + "\t precison = " + mc.getPrecision());
|
||||
System.err.println("expected scale = " + preferredScale);
|
||||
*/
|
||||
|
||||
BigDecimal result = element.subtract(zero, mc);
|
||||
if (result.scale() != preferredScale ||
|
||||
result.compareTo(element) != 0) {
|
||||
failures++;
|
||||
System.err.println("Expected scale " + preferredScale +
|
||||
" result scale was " + result.scale() +
|
||||
" ; value was " + result);
|
||||
}
|
||||
|
||||
result = zero.subtract(element, mc);
|
||||
if (result.scale() != preferredScale ||
|
||||
result.compareTo(element.negate()) != 0) {
|
||||
failures++;
|
||||
System.err.println("Expected scale " + preferredScale +
|
||||
" result scale was " + result.scale() +
|
||||
" ; value was " + result);
|
||||
}
|
||||
|
||||
result = element.negate().subtract(zero, mc);
|
||||
if (result.scale() != preferredScale ||
|
||||
result.compareTo(element.negate()) != 0) {
|
||||
failures++;
|
||||
System.err.println("Expected scale " + preferredScale +
|
||||
" result scale was " + result.scale() +
|
||||
" ; value was " + result);
|
||||
}
|
||||
|
||||
result = zero.subtract(element.negate(), mc);
|
||||
if (result.scale() != preferredScale ||
|
||||
result.compareTo(element) != 0) {
|
||||
failures++;
|
||||
System.err.println("Expected scale " + preferredScale +
|
||||
" result scale was " + result.scale() +
|
||||
" ; value was " + result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int multiplyTests() {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal ones[] = {
|
||||
BigDecimal.valueOf(1, 0),
|
||||
BigDecimal.valueOf(10, 1),
|
||||
BigDecimal.valueOf(1000, 3),
|
||||
BigDecimal.valueOf(100000000, 8),
|
||||
};
|
||||
|
||||
List<BigDecimal> values = new LinkedList<BigDecimal>();
|
||||
values.addAll(Arrays.asList(zeros));
|
||||
values.addAll(Arrays.asList(ones));
|
||||
|
||||
for(BigDecimal zero1: zeros) {
|
||||
for(BigDecimal value: values) {
|
||||
BigDecimal expected = new BigDecimal(BigInteger.ZERO,
|
||||
(int)Math.min(Math.max((long)zero1.scale()+value.scale(),
|
||||
Integer.MIN_VALUE ),
|
||||
Integer.MAX_VALUE ) );
|
||||
BigDecimal result;
|
||||
|
||||
if(! (result=zero1.multiply(value)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For classic exact multiply, expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
if(! (result=zero1.multiply(value, MathContext.UNLIMITED)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For UNLIMITED math context multiply," +
|
||||
" expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
if(! (result=zero1.multiply(value, longEnough)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For longEnough math context multiply," +
|
||||
" expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int divideTests() {
|
||||
int failures = 0;
|
||||
|
||||
BigDecimal [] ones = {
|
||||
BigDecimal.valueOf(1, 0),
|
||||
BigDecimal.valueOf(10, -1),
|
||||
BigDecimal.valueOf(100, -2),
|
||||
BigDecimal.valueOf(1000, -3),
|
||||
BigDecimal.valueOf(1000000, -5),
|
||||
};
|
||||
|
||||
for(BigDecimal one: ones) {
|
||||
for(BigDecimal zero: zeros) {
|
||||
BigDecimal expected = new BigDecimal(BigInteger.ZERO,
|
||||
(int)Math.min(Math.max((long)zero.scale() - one.scale(),
|
||||
Integer.MIN_VALUE ),
|
||||
Integer.MAX_VALUE ) );
|
||||
BigDecimal result;
|
||||
|
||||
if(! (result=zero.divide(one)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For classic exact divide, expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
if(! (result=zero.divide(one, MathContext.UNLIMITED)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For UNLIMITED math context divide," +
|
||||
" expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
if(! (result=zero.divide(one, longEnough)).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("For longEnough math context divide," +
|
||||
" expected scale of " +
|
||||
expected.scale() + "; got " +
|
||||
result.scale() + ".");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int setScaleTests() {
|
||||
int failures = 0;
|
||||
|
||||
int scales[] = {
|
||||
Integer.MIN_VALUE,
|
||||
Integer.MIN_VALUE+1,
|
||||
-10000000,
|
||||
-3,
|
||||
-2,
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
10,
|
||||
10000000,
|
||||
Integer.MAX_VALUE-1,
|
||||
Integer.MAX_VALUE
|
||||
};
|
||||
|
||||
for(BigDecimal zero: zeros) {
|
||||
for(int scale: scales) {
|
||||
try {
|
||||
BigDecimal bd = zero.setScale(scale);
|
||||
}
|
||||
catch (ArithmeticException e) {
|
||||
failures++;
|
||||
System.err.println("Exception when trying to set a scale of " + scale +
|
||||
" on " + zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int toEngineeringStringTests() {
|
||||
int failures = 0;
|
||||
|
||||
String [][] testCases = {
|
||||
{"0E+10", "0.00E+12"},
|
||||
{"0E+9", "0E+9"},
|
||||
{"0E+8", "0.0E+9"},
|
||||
{"0E+7", "0.00E+9"},
|
||||
|
||||
{"0E-10", "0.0E-9"},
|
||||
{"0E-9", "0E-9"},
|
||||
{"0E-8", "0.00E-6"},
|
||||
{"0E-7", "0.0E-6"},
|
||||
};
|
||||
|
||||
for(String[] testCase: testCases) {
|
||||
BigDecimal bd = new BigDecimal(testCase[0]);
|
||||
String result = bd.toEngineeringString();
|
||||
|
||||
if (!result.equals(testCase[1]) ||
|
||||
!bd.equals(new BigDecimal(result))) {
|
||||
failures++;
|
||||
System.err.println("From input ``" + testCase[0] + ",'' " +
|
||||
" bad engineering string output ``" + result +
|
||||
"''; expected ``" + testCase[1] + ".''");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int ulpTests() {
|
||||
int failures = 0;
|
||||
|
||||
for(BigDecimal zero: zeros) {
|
||||
BigDecimal result;
|
||||
BigDecimal expected = BigDecimal.valueOf(1, zero.scale());
|
||||
|
||||
if (! (result=zero.ulp()).equals(expected) ) {
|
||||
failures++;
|
||||
System.err.println("Unexpected ulp value for zero value " +
|
||||
zero + "; expected " + expected +
|
||||
", got " + result);
|
||||
}
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int setScaleDoesNotMutateTest() {
|
||||
BigDecimal total = new BigDecimal("258815507198903607775511093103396443816569106750031264155319238473795838680758514810110764742309284477206138527975952150289602995045050194333030191178778772026538699925775139201970526695485362661420908248887297829319881475178467494779683293036572059595504702727301324759997409522995072582369210284334718757260859794972695026582432867589093687280300148141501712013226636373167978223780290547640482160818746599330924736802844173226042389174403401903999447463440670236056324929325189403433689"
|
||||
+ ".426167432065785331444814035799717606745777287606858873045971898862329763544687891847664736523584843544347118836628373041412918374550458884706686730726101338872517021688769782894793734049819222924171842793485919753186993388451909096042127903835765393729547730953942175461146061715108701615615142134282261293656760570061554783195726716403304101469782303957325142638493327692352838806741611887655695029948975509680496573999174402058593454203190963443179532640446352828089016874853634851387762579319853267317320515941105912189838719919259277721994880193541634872882180184303434360412344059435559680494807415573269199203376126242271766939666939316648575065702750502798973418978204972336924254702551350654650573582614211506856383897692911422458286912085339575875324832979140870119455620532272318122103640233069115700020760625493816902806241630788230268031695140687964931377988962507263990468276009750998066442971308866347136022907166625330623130307555914930120150437900510530537258665172619821272937026713977709974434967165159545592482710663639966781678268622620229577009317698254134914742098420792313931843709810905414336383757407675429663714210967924767434203021205270369316797752411974617662200898086335322218191674846795163102021505555508444216708745911194321674887527227200297039471799580744303346354057273540730643842091810899490590914195225087593013834388801018488174855060306804024894292757613618190472234110859436472645203753139820658279559340251226992556744343475086923568365637919479462424794554522865559888240039662899509652221329892034706445253487898044421278283079233226845124525434586324657471286953226255430662125870993375281512713207125720748163498642795960457639954616530163959004770092547297392499137383176609646505351001304840762905826237024982330597805063521162285806541220110524989649256399233792799406995068469271941269511818994954109392839548141262324660472253632382325038836831429045617036015122388070240133760858500132713255407855625837956886349324981003917084922808187223285051144454915441134217743066575863563572152133978905444998209075763950909784148142018992367290485890072303179512881131769414783097454103103347826517701720263541869335631166977965013552647906729408522950996105479525445916501155305220090853891226367184989434453290788068397817927893708837722255115237672194162924260945492012622891770365546831236789867922136747819364833843397165107825773447549885351449899330007200651144003961228091210630807333236718793283427788965479074476288255387824982443633190938302785760754436525586544523339170400053128503337395428393881357669568532722167493096151221381017320147344991331421789379785964440840684363041795410525097564979585773948558651896834067324427900848255265001498890329859444233861478388742393060996236783742654761350763876989363052609107226398858310051497856931093693697981165801539060516895227818925342535261227134364063673285588256280386915163875872231395348293505967057794409379709079685798908660258077792158532257603211711587587586356431658240229896344639704");
|
||||
if (total.setScale(0, RoundingMode.DOWN).equals(total.setScale(0, RoundingMode.DOWN))) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += addTests();
|
||||
failures += subtractTests();
|
||||
failures += multiplyTests();
|
||||
failures += divideTests();
|
||||
failures += setScaleTests();
|
||||
failures += toEngineeringStringTests();
|
||||
failures += ulpTests();
|
||||
failures += setScaleDoesNotMutateTest();
|
||||
|
||||
if (failures > 0 ) {
|
||||
throw new RuntimeException("Incurred " + failures + " failures" +
|
||||
" testing the preservation of zero scales.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @run main BigIntegerParallelMultiplyTest
|
||||
* @summary tests parallelMultiply() method in BigInteger
|
||||
* @author Heinz Kabutz heinz@javaspecialists.eu
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.function.BinaryOperator;
|
||||
|
||||
/**
|
||||
* This is a simple test class created to ensure that the results
|
||||
* of multiply() are the same as multiplyParallel(). We calculate
|
||||
* the Fibonacci numbers using Dijkstra's sum of squares to get
|
||||
* very large numbers (hundreds of thousands of bits).
|
||||
*
|
||||
* @author Heinz Kabutz, heinz@javaspecialists.eu
|
||||
*/
|
||||
public class BigIntegerParallelMultiplyTest {
|
||||
public static BigInteger fibonacci(int n, BinaryOperator<BigInteger> multiplyOperator) {
|
||||
if (n == 0) return BigInteger.ZERO;
|
||||
if (n == 1) return BigInteger.ONE;
|
||||
|
||||
int half = (n + 1) / 2;
|
||||
BigInteger f0 = fibonacci(half - 1, multiplyOperator);
|
||||
BigInteger f1 = fibonacci(half, multiplyOperator);
|
||||
if (n % 2 == 1) {
|
||||
BigInteger b0 = multiplyOperator.apply(f0, f0);
|
||||
BigInteger b1 = multiplyOperator.apply(f1, f1);
|
||||
return b0.add(b1);
|
||||
} else {
|
||||
BigInteger b0 = f0.shiftLeft(1).add(f1);
|
||||
return multiplyOperator.apply(b0, f1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
compare(1000, 324);
|
||||
compare(10_000, 3473);
|
||||
compare(100_000, 34883);
|
||||
compare(1_000_000, 347084);
|
||||
}
|
||||
|
||||
private static void compare(int n, int expectedBitCount) {
|
||||
BigInteger multiplyResult = fibonacci(n, BigInteger::multiply);
|
||||
BigInteger parallelMultiplyResult = fibonacci(n, BigInteger::parallelMultiply);
|
||||
checkBitCount(n, expectedBitCount, multiplyResult);
|
||||
checkBitCount(n, expectedBitCount, parallelMultiplyResult);
|
||||
if (!multiplyResult.equals(parallelMultiplyResult))
|
||||
throw new AssertionError("multiply() and parallelMultiply() give different results");
|
||||
}
|
||||
|
||||
private static void checkBitCount(int n, int expectedBitCount, BigInteger number) {
|
||||
if (number.bitCount() != expectedBitCount)
|
||||
throw new AssertionError(
|
||||
"bitCount of fibonacci(" + n + ") was expected to be " + expectedBitCount
|
||||
+ " but was " + number.bitCount());
|
||||
}
|
||||
}
|
||||
1558
test/jdk/java/math/BigInteger/BigIntegerTest.java
Normal file
1558
test/jdk/java/math/BigInteger/BigIntegerTest.java
Normal file
File diff suppressed because it is too large
Load diff
65
test/jdk/java/math/BigInteger/BitLengthOverflow.java
Normal file
65
test/jdk/java/math/BigInteger/BitLengthOverflow.java
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6910473 8272541
|
||||
* @summary Test that bitLength() is not negative
|
||||
* @author Dmitry Nadezhin
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BitLengthOverflow {
|
||||
private static void test(Supplier<BigInteger> s) {
|
||||
try {
|
||||
BigInteger x = s.get();
|
||||
System.out.println("Surprisingly passed with correct bitLength() " +
|
||||
x.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
System.out.println("Overflow reported by ArithmeticException, as expected");
|
||||
} catch (OutOfMemoryError e) {
|
||||
// possible
|
||||
System.err.println("BitLengthOverflow skipped: OutOfMemoryError");
|
||||
System.err.println("Run jtreg with -javaoption:-Xmx8g");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
test(() -> {
|
||||
// x = pow(2,Integer.MAX_VALUE)
|
||||
BigInteger x = BigInteger.ONE.shiftLeft(Integer.MAX_VALUE);
|
||||
if (x.bitLength() != (1L << 31)) {
|
||||
throw new RuntimeException("Incorrect bitLength() " +
|
||||
x.bitLength());
|
||||
}
|
||||
return x;
|
||||
});
|
||||
test(() -> {
|
||||
BigInteger a = BigInteger.ONE.shiftLeft(1073742825);
|
||||
BigInteger b = BigInteger.ONE.shiftLeft(1073742825);
|
||||
return a.multiply(b);
|
||||
});
|
||||
}
|
||||
}
|
||||
148
test/jdk/java/math/BigInteger/ByteArrayConstructorTest.java
Normal file
148
test/jdk/java/math/BigInteger/ByteArrayConstructorTest.java
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.test.lib.RandomFactory;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.Accessor;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8319174
|
||||
* @summary Exercises minimality of BigInteger.mag field (use -Dseed=X to set PRANDOM seed)
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.RandomFactory
|
||||
* @build java.base/java.math.Accessor
|
||||
* @key randomness
|
||||
* @run junit/othervm -DmaxDurationMillis=3000 ByteArrayConstructorTest
|
||||
*/
|
||||
public class ByteArrayConstructorTest {
|
||||
|
||||
private static final int DEFAULT_MAX_DURATION_MILLIS = 3_000;
|
||||
|
||||
public static final int N = 1_024;
|
||||
|
||||
private static int maxDurationMillis;
|
||||
private static final Random rnd = RandomFactory.getRandom();
|
||||
private volatile boolean stop = false;
|
||||
|
||||
@BeforeAll
|
||||
static void setMaxDurationMillis() {
|
||||
maxDurationMillis = Math.max(maxDurationMillis(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonNegative() throws InterruptedException {
|
||||
byte[] ba = nonNegativeBytes();
|
||||
doBigIntegers(ba, ba[0]); // a mask to flip to 0 and back to ba[0]
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegative() throws InterruptedException {
|
||||
byte[] ba = negativeBytes();
|
||||
doBigIntegers(ba, (byte) ~ba[0]); // a mask to flip to -1 and back to ba[0]
|
||||
}
|
||||
|
||||
/*
|
||||
* Starts a thread th that keeps flipping the "sign" byte in the array ba
|
||||
* from the original value to 0 or -1 and back, depending on ba[0] being
|
||||
* non-negative or negative, resp.
|
||||
* (ba is "big endian", the least significant byte is the one with the
|
||||
* highest index.)
|
||||
*
|
||||
* In the meantime, the current thread keeps creating BigInteger instances
|
||||
* with ba and checks that the internal invariant holds, despite the
|
||||
* attempts by thread th to racily modify ba.
|
||||
* It does so at least as indicated by maxDurationMillis.
|
||||
*
|
||||
* Finally, this thread requests th to stop and joins with it, either
|
||||
* because maxDurationMillis has expired, or because of an invalid invariant.
|
||||
*/
|
||||
private void doBigIntegers(byte[] ba, byte mask) throws InterruptedException {
|
||||
Thread th = new Thread(() -> {
|
||||
while (!stop) {
|
||||
ba[0] ^= mask;
|
||||
}
|
||||
});
|
||||
th.start();
|
||||
|
||||
try {
|
||||
createBigIntegers(maxDurationMillis, ba);
|
||||
} finally {
|
||||
stop = true;
|
||||
th.join(1_000);
|
||||
}
|
||||
}
|
||||
|
||||
private void createBigIntegers(int maxDurationMillis, byte[] ba) {
|
||||
long start = System.currentTimeMillis();
|
||||
while (System.currentTimeMillis() - start < maxDurationMillis) {
|
||||
BigInteger bi = new BigInteger(ba);
|
||||
int[] mag = Accessor.mag(bi);
|
||||
assertTrue(mag.length == 0 || mag[0] != 0,
|
||||
String.format("inconsistent BigInteger: mag.length=%d, mag[0]=%d",
|
||||
mag.length, mag[0]));
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] nonNegativeBytes() {
|
||||
byte[] ba = new byte[1 + N];
|
||||
byte b0;
|
||||
while ((b0 = (byte) rnd.nextInt()) < 0); // empty body
|
||||
rnd.nextBytes(ba);
|
||||
ba[0] = b0;
|
||||
/* Except for ba[0], fill most significant half with zeros. */
|
||||
for (int i = 1; i <= N / 2; ++i) {
|
||||
ba[i] = 0;
|
||||
}
|
||||
return ba;
|
||||
}
|
||||
|
||||
private byte[] negativeBytes() {
|
||||
byte[] ba = new byte[1 + N];
|
||||
byte b0;
|
||||
while ((b0 = (byte) rnd.nextInt()) >= 0); // empty body
|
||||
rnd.nextBytes(ba);
|
||||
ba[0] = b0;
|
||||
/* Except for ba[0], fill most significant half with -1 bytes. */
|
||||
for (int i = 1; i <= N / 2; ++i) {
|
||||
ba[i] = -1;
|
||||
}
|
||||
return ba;
|
||||
}
|
||||
|
||||
private static int maxDurationMillis() {
|
||||
try {
|
||||
return Integer.parseInt(System.getProperty("maxDurationMillis",
|
||||
Integer.toString(DEFAULT_MAX_DURATION_MILLIS)));
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
return DEFAULT_MAX_DURATION_MILLIS;
|
||||
}
|
||||
|
||||
}
|
||||
127
test/jdk/java/math/BigInteger/CompareToTests.java
Normal file
127
test/jdk/java/math/BigInteger/CompareToTests.java
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6473768
|
||||
* @summary Tests of BigInteger.compareTo
|
||||
*/
|
||||
import java.math.*;
|
||||
import static java.math.BigInteger.*;
|
||||
|
||||
public class CompareToTests {
|
||||
private static int compareToTests() {
|
||||
int failures = 0;
|
||||
|
||||
final BigInteger MINUS_ONE = BigInteger.ONE.negate();
|
||||
final BigInteger TWO_POW_126 = ONE.shiftLeft(126);
|
||||
final BigInteger TWO_POW_127 = ONE.shiftLeft(127);
|
||||
final BigInteger TWO_POW_128 = ONE.shiftLeft(128);
|
||||
|
||||
// First operand, second operand, expected compareTo result
|
||||
BigInteger [][] testCases = {
|
||||
// Basics
|
||||
{valueOf(0), valueOf(0), ZERO},
|
||||
{valueOf(0), valueOf(1), MINUS_ONE},
|
||||
{valueOf(1), valueOf(2), MINUS_ONE},
|
||||
{valueOf(2), valueOf(1), ONE},
|
||||
{valueOf(10), valueOf(10), ZERO},
|
||||
|
||||
// Various relative lengths of internal mag array.
|
||||
{TWO_POW_127, TWO_POW_127, ZERO},
|
||||
{TWO_POW_127.negate(), TWO_POW_127, MINUS_ONE},
|
||||
|
||||
{TWO_POW_128.or(TWO_POW_126), TWO_POW_128, ONE},
|
||||
{TWO_POW_128.or(TWO_POW_126), TWO_POW_128.negate(), ONE},
|
||||
|
||||
{TWO_POW_128, TWO_POW_128.or(TWO_POW_126), MINUS_ONE},
|
||||
{TWO_POW_128.negate(), TWO_POW_128.or(TWO_POW_126), MINUS_ONE},
|
||||
|
||||
{TWO_POW_127, TWO_POW_128, MINUS_ONE},
|
||||
{TWO_POW_127.negate(), TWO_POW_128, MINUS_ONE},
|
||||
|
||||
{TWO_POW_128, TWO_POW_127, ONE},
|
||||
{TWO_POW_128.negate(), TWO_POW_127, MINUS_ONE},
|
||||
|
||||
// Long boundary and near boundary values
|
||||
{valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO},
|
||||
{valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
|
||||
{valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
{valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
|
||||
{valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
{valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MAX_VALUE), ONE},
|
||||
|
||||
{valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE},
|
||||
{valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MAX_VALUE), ZERO},
|
||||
|
||||
{valueOf(Long.MAX_VALUE), valueOf(Long.MIN_VALUE), ONE},
|
||||
{valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE},
|
||||
|
||||
{valueOf(Long.MAX_VALUE-1), valueOf(Long.MIN_VALUE), ONE},
|
||||
{valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MIN_VALUE), ONE},
|
||||
|
||||
{valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO},
|
||||
{valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE},
|
||||
|
||||
{valueOf(Long.MIN_VALUE+1), valueOf(Long.MIN_VALUE), ONE},
|
||||
{valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MIN_VALUE), ONE},
|
||||
};
|
||||
|
||||
for (BigInteger[] testCase : testCases) {
|
||||
BigInteger a = testCase[0];
|
||||
BigInteger a_negate = a.negate();
|
||||
BigInteger b = testCase[1];
|
||||
BigInteger b_negate = b.negate();
|
||||
int expected = testCase[2].intValue();
|
||||
|
||||
failures += compareToTest(a, b, expected);
|
||||
failures += compareToTest(a_negate, b_negate, -expected);
|
||||
}
|
||||
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int compareToTest(BigInteger a, BigInteger b, int expected) {
|
||||
int result = a.compareTo(b);
|
||||
int failed = (result==expected) ? 0 : 1;
|
||||
if (failed == 1) {
|
||||
System.err.println("(" + a + ").compareTo(" + b + ") => " + result +
|
||||
"\n\tExpected " + expected);
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += compareToTests();
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
" failures while testing exact compareTo.");
|
||||
}
|
||||
}
|
||||
}
|
||||
50
test/jdk/java/math/BigInteger/DoubleValueOverflow.java
Normal file
50
test/jdk/java/math/BigInteger/DoubleValueOverflow.java
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8021203
|
||||
* @summary Test that doubleValue() doesn't overflow
|
||||
* @author Dmitry Nadezhin
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class DoubleValueOverflow {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
BigInteger x = BigInteger.valueOf(2).shiftLeft(Integer.MAX_VALUE); // x = pow(2,pow(2,31))
|
||||
if (x.doubleValue() != Double.POSITIVE_INFINITY) {
|
||||
throw new RuntimeException("Incorrect doubleValue() " + x.doubleValue());
|
||||
}
|
||||
System.out.println("Passed with correct result");
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
System.out.println("Overflow is reported by ArithmeticException, as expected");
|
||||
} catch (OutOfMemoryError e) {
|
||||
// possible
|
||||
System.err.println("DoubleValueOverflow skipped: OutOfMemoryError");
|
||||
System.err.println("Run jtreg with -javaoption:-Xmx8g");
|
||||
}
|
||||
}
|
||||
}
|
||||
68
test/jdk/java/math/BigInteger/ExtremeShiftingTests.java
Normal file
68
test/jdk/java/math/BigInteger/ExtremeShiftingTests.java
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6371401
|
||||
* @summary Tests of shiftLeft and shiftRight on Integer.MIN_VALUE
|
||||
* @requires os.maxMemory >= 1g
|
||||
* @run main/othervm -Xmx512m ExtremeShiftingTests
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
import static java.math.BigInteger.*;
|
||||
|
||||
public class ExtremeShiftingTests {
|
||||
public static void main(String... args) {
|
||||
BigInteger bi = ONE.shiftLeft(Integer.MIN_VALUE);
|
||||
if (!bi.equals(ZERO))
|
||||
throw new RuntimeException("1 << " + Integer.MIN_VALUE);
|
||||
|
||||
bi = ZERO.shiftLeft(Integer.MIN_VALUE);
|
||||
if (!bi.equals(ZERO))
|
||||
throw new RuntimeException("0 << " + Integer.MIN_VALUE);
|
||||
|
||||
bi = BigInteger.valueOf(-1);
|
||||
bi = bi.shiftLeft(Integer.MIN_VALUE);
|
||||
if (!bi.equals(BigInteger.valueOf(-1)))
|
||||
throw new RuntimeException("-1 << " + Integer.MIN_VALUE);
|
||||
|
||||
try {
|
||||
ONE.shiftRight(Integer.MIN_VALUE);
|
||||
throw new RuntimeException("1 >> " + Integer.MIN_VALUE);
|
||||
} catch (ArithmeticException ae) {
|
||||
; // Expected
|
||||
}
|
||||
|
||||
bi = ZERO.shiftRight(Integer.MIN_VALUE);
|
||||
if (!bi.equals(ZERO))
|
||||
throw new RuntimeException("0 >> " + Integer.MIN_VALUE);
|
||||
|
||||
try {
|
||||
BigInteger.valueOf(-1).shiftRight(Integer.MIN_VALUE);
|
||||
throw new RuntimeException("-1 >> " + Integer.MIN_VALUE);
|
||||
} catch (ArithmeticException ae) {
|
||||
; // Expected
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
74
test/jdk/java/math/BigInteger/HashCode.java
Normal file
74
test/jdk/java/math/BigInteger/HashCode.java
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8310813
|
||||
* @summary Check hashCode implementation against reference values
|
||||
*/
|
||||
public class HashCode {
|
||||
|
||||
// This test guards against inadvertent changes to BigInteger.hashCode,
|
||||
// by checking generated hashCode values against reference values
|
||||
// captured immediately before 8310813
|
||||
|
||||
public static void main(String[] args) {
|
||||
equals( 0, BigInteger.ZERO);
|
||||
equals( 1, BigInteger.ONE);
|
||||
equals( 2, BigInteger.TWO);
|
||||
equals( 10, BigInteger.TEN);
|
||||
equals( -128, BigInteger.valueOf(Byte.MIN_VALUE));
|
||||
equals( 127, BigInteger.valueOf(Byte.MAX_VALUE));
|
||||
equals( -32768, BigInteger.valueOf(Short.MIN_VALUE));
|
||||
equals( 32767, BigInteger.valueOf(Short.MAX_VALUE));
|
||||
equals( 0, BigInteger.valueOf(Character.MIN_VALUE));
|
||||
equals( 65535, BigInteger.valueOf(Character.MAX_VALUE));
|
||||
equals(-2147483648, BigInteger.valueOf(Integer.MIN_VALUE));
|
||||
equals( 2147483647, BigInteger.valueOf(Integer.MAX_VALUE));
|
||||
equals(-2147483648, BigInteger.valueOf(Long.MIN_VALUE));
|
||||
equals( 2147483616, BigInteger.valueOf(Long.MAX_VALUE));
|
||||
equals( -1, BigInteger.valueOf(-1));
|
||||
|
||||
// a 37-byte negative number, generated at random
|
||||
equals( 1428257188, new BigInteger("""
|
||||
-5573526435790097067262357965922443376770234990700620666883\
|
||||
2705705469477701887396205062479"""));
|
||||
// a 123-byte positive number, generated at random
|
||||
equals( -412503667, new BigInteger("""
|
||||
13093241912251296135908856604398494061635394768699286753760\
|
||||
22827291528069076557720973813183142494646514532475660126948\
|
||||
43316474303725664231917408569680292008962577772928370936861\
|
||||
12952691245923210726443405774197400117701581498597123145452\
|
||||
15111774818054200162634242662445757757255702394598235971294\
|
||||
50"""));
|
||||
}
|
||||
|
||||
private static void equals(int expectedHashCode, BigInteger i) {
|
||||
int actualHashCode = i.hashCode();
|
||||
if (expectedHashCode != actualHashCode)
|
||||
throw new AssertionError("%s: expectedHashCode=%s, actual=%s"
|
||||
.formatted(i, expectedHashCode, actualHashCode));
|
||||
}
|
||||
}
|
||||
221
test/jdk/java/math/BigInteger/LargeValueExceptions.java
Normal file
221
test/jdk/java/math/BigInteger/LargeValueExceptions.java
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8200698
|
||||
* @summary Tests that exceptions are thrown for ops which would overflow
|
||||
* @requires (sun.arch.data.model == "64" & os.maxMemory >= 4g)
|
||||
* @run junit/othervm/timeout=480 -Xmx4g LargeValueExceptions
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import static java.math.BigInteger.ONE;
|
||||
|
||||
//
|
||||
// The intent of this test is to probe the boundaries between overflow and
|
||||
// non-overflow, principally for multiplication and squaring, specifically
|
||||
// the largest values which should not overflow and the smallest values which
|
||||
// should. The transition values used are not necessarily at the exact
|
||||
// boundaries but should be "close." Quite a few different values were used
|
||||
// experimentally before settling on the ones in this test. For multiplication
|
||||
// and squaring all cases are exercised: definite overflow and non-overflow
|
||||
// which can be detected "up front," and "indefinite" overflow, i.e., overflow
|
||||
// which cannot be detected up front so further calculations are required.
|
||||
//
|
||||
// Testing negative values is unnecessary. For both multiplication and squaring
|
||||
// the paths lead to the Toom-Cook algorithm where the signum is used only to
|
||||
// determine the sign of the result and not in the intermediate calculations.
|
||||
// This is also true for exponentiation.
|
||||
//
|
||||
// @Test annotations with optional element "enabled" set to "false" should
|
||||
// succeed when "enabled" is set to "true" but they take too to run in the
|
||||
// course of the typical regression test execution scenario.
|
||||
//
|
||||
public class LargeValueExceptions {
|
||||
// BigInteger.MAX_MAG_LENGTH
|
||||
private static final int MAX_INTS = 1 << 26;
|
||||
|
||||
// Number of bits corresponding to MAX_INTS
|
||||
private static final long MAX_BITS = (0xffffffffL & MAX_INTS) << 5L;
|
||||
|
||||
// Half BigInteger.MAX_MAG_LENGTH
|
||||
private static final int MAX_INTS_HALF = MAX_INTS / 2;
|
||||
|
||||
// --- squaring ---
|
||||
|
||||
// Largest no overflow determined by examining data lengths alone.
|
||||
@Test
|
||||
@Disabled
|
||||
public void squareNoOverflow() {
|
||||
BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1).subtract(ONE);
|
||||
BigInteger y = x.multiply(x);
|
||||
}
|
||||
|
||||
// Smallest no overflow determined by extra calculations.
|
||||
@Test
|
||||
@Disabled
|
||||
public void squareIndefiniteOverflowSuccess() {
|
||||
BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1);
|
||||
BigInteger y = x.multiply(x);
|
||||
}
|
||||
|
||||
// Largest overflow detected by extra calculations.
|
||||
@Test
|
||||
@Disabled
|
||||
public void squareIndefiniteOverflowFailure() {
|
||||
Assertions.assertThrows(ArithmeticException.class, () -> {
|
||||
BigInteger x = ONE.shiftLeft(16*MAX_INTS).subtract(ONE);
|
||||
BigInteger y = x.multiply(x);
|
||||
});
|
||||
}
|
||||
|
||||
// Smallest overflow detected by examining data lengths alone.
|
||||
@Test
|
||||
public void squareDefiniteOverflow() {
|
||||
Assertions.assertThrows(ArithmeticException.class, () -> {
|
||||
BigInteger x = ONE.shiftLeft(16*MAX_INTS);
|
||||
BigInteger y = x.multiply(x);
|
||||
});
|
||||
}
|
||||
|
||||
// --- multiplication ---
|
||||
|
||||
// Largest no overflow determined by examining data lengths alone.
|
||||
@Test
|
||||
@Disabled
|
||||
public void multiplyNoOverflow() {
|
||||
final int halfMaxBits = MAX_INTS_HALF << 5;
|
||||
|
||||
BigInteger x = ONE.shiftLeft(halfMaxBits).subtract(ONE);
|
||||
BigInteger y = ONE.shiftLeft(halfMaxBits - 1).subtract(ONE);
|
||||
BigInteger z = x.multiply(y);
|
||||
}
|
||||
|
||||
// Smallest no overflow determined by extra calculations.
|
||||
@Test
|
||||
@Disabled
|
||||
public void multiplyIndefiniteOverflowSuccess() {
|
||||
BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2) - 1);
|
||||
long m = MAX_BITS - x.bitLength();
|
||||
|
||||
BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2) - 1);
|
||||
long n = MAX_BITS - y.bitLength();
|
||||
|
||||
if (m + n != MAX_BITS) {
|
||||
throw new RuntimeException("Unexpected leading zero sum");
|
||||
}
|
||||
|
||||
BigInteger z = x.multiply(y);
|
||||
}
|
||||
|
||||
// Largest overflow detected by extra calculations.
|
||||
@Test
|
||||
@Disabled
|
||||
public void multiplyIndefiniteOverflowFailure() {
|
||||
Assertions.assertThrows(ArithmeticException.class, () -> {
|
||||
BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE);
|
||||
long m = MAX_BITS - x.bitLength();
|
||||
|
||||
BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE);
|
||||
long n = MAX_BITS - y.bitLength();
|
||||
|
||||
if (m + n != MAX_BITS) {
|
||||
throw new RuntimeException("Unexpected leading zero sum");
|
||||
}
|
||||
|
||||
BigInteger z = x.multiply(y);
|
||||
});
|
||||
}
|
||||
|
||||
// Smallest overflow detected by examining data lengths alone.
|
||||
@Test
|
||||
public void multiplyDefiniteOverflow() {
|
||||
Assertions.assertThrows(ArithmeticException.class, () -> {
|
||||
// multiply by 4 as MAX_INTS_HALF refers to ints
|
||||
byte[] xmag = new byte[4*MAX_INTS_HALF];
|
||||
xmag[0] = (byte)0xff;
|
||||
BigInteger x = new BigInteger(1, xmag);
|
||||
|
||||
byte[] ymag = new byte[4*MAX_INTS_HALF + 1];
|
||||
ymag[0] = (byte)0xff;
|
||||
BigInteger y = new BigInteger(1, ymag);
|
||||
|
||||
BigInteger z = x.multiply(y);
|
||||
});
|
||||
}
|
||||
|
||||
// --- exponentiation ---
|
||||
|
||||
@Test
|
||||
public void powOverflow() {
|
||||
Assertions.assertThrows(ArithmeticException.class, () -> {
|
||||
BigInteger.TEN.pow(Integer.MAX_VALUE);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void powOverflow1() {
|
||||
Assertions.assertThrows(ArithmeticException.class, () -> {
|
||||
int shift = 20;
|
||||
int exponent = 1 << shift;
|
||||
BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent));
|
||||
BigInteger y = x.pow(exponent);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void powOverflow2() {
|
||||
Assertions.assertThrows(ArithmeticException.class, () -> {
|
||||
int shift = 20;
|
||||
int exponent = 1 << shift;
|
||||
BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).add(ONE);
|
||||
BigInteger y = x.pow(exponent);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void powOverflow3() {
|
||||
Assertions.assertThrows(ArithmeticException.class, () -> {
|
||||
int shift = 20;
|
||||
int exponent = 1 << shift;
|
||||
BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).subtract(ONE);
|
||||
BigInteger y = x.pow(exponent);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void powOverflow4() {
|
||||
int shift = 20;
|
||||
int exponent = 1 << shift;
|
||||
BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent - 1)).add(ONE);
|
||||
BigInteger y = x.pow(exponent);
|
||||
}
|
||||
}
|
||||
57
test/jdk/java/math/BigInteger/ModInvTime.java
Normal file
57
test/jdk/java/math/BigInteger/ModInvTime.java
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8225603
|
||||
* @summary Tests whether modInverse() completes in a reasonable time
|
||||
* @run main/othervm ModInvTime
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class ModInvTime {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
BigInteger prime = new BigInteger("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643");
|
||||
BigInteger s = new BigInteger("9552729729729327851382626410162104591956625415831952158766936536163093322096473638446154604799898109762512409920799");
|
||||
System.out.format("int length: %d, modulus length: %d%n",
|
||||
s.bitLength(), prime.bitLength());
|
||||
|
||||
System.out.println("Computing modular inverse ...");
|
||||
BigInteger mi = s.modInverse(prime);
|
||||
System.out.format("Modular inverse: %s%n", mi);
|
||||
check(s, prime, mi);
|
||||
|
||||
BigInteger ns = s.negate();
|
||||
BigInteger nmi = ns.modInverse(prime);
|
||||
System.out.format("Modular inverse of negation: %s%n", nmi);
|
||||
check(ns, prime, nmi);
|
||||
}
|
||||
|
||||
public static void check(BigInteger val, BigInteger mod, BigInteger inv) {
|
||||
BigInteger r = inv.multiply(val).remainder(mod);
|
||||
if (r.signum() == -1)
|
||||
r = r.add(mod);
|
||||
if (!r.equals(BigInteger.ONE))
|
||||
throw new RuntimeException("Numerically incorrect modular inverse");
|
||||
}
|
||||
}
|
||||
59
test/jdk/java/math/BigInteger/ModPow.java
Normal file
59
test/jdk/java/math/BigInteger/ModPow.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4181191 8215759
|
||||
* @summary test BigInteger modPow method (use -Dseed=X to set PRNG seed)
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.RandomFactory
|
||||
* @run main ModPow
|
||||
* @key randomness
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
import java.util.Random;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
|
||||
public class ModPow {
|
||||
public static void main(String[] args) {
|
||||
Random rnd = RandomFactory.getRandom();
|
||||
|
||||
for (int i=0; i<2000; i++) {
|
||||
// Clamp random modulus to a positive value or modPow() will
|
||||
// throw an ArithmeticException.
|
||||
BigInteger m = new BigInteger(800, rnd).max(BigInteger.ONE);
|
||||
BigInteger base = new BigInteger(16, rnd);
|
||||
if (rnd.nextInt() % 1 == 0)
|
||||
base = base.negate();
|
||||
BigInteger exp = new BigInteger(8, rnd);
|
||||
|
||||
BigInteger z = base.modPow(exp, m);
|
||||
BigInteger w = base.pow(exp.intValue()).mod(m);
|
||||
if (!z.equals(w)){
|
||||
System.err.println(base +" ** " + exp + " mod "+ m);
|
||||
System.err.println("modPow : " + z);
|
||||
System.err.println("pow.mod: " + w);
|
||||
throw new RuntimeException("BigInteger modPow failure.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
102
test/jdk/java/math/BigInteger/ModPow65537.java
Normal file
102
test/jdk/java/math/BigInteger/ModPow65537.java
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.RandomFactory
|
||||
* @run main ModPow65537
|
||||
* @bug 4891312 8074460 8078672
|
||||
* @summary verify that modPow() not broken by the special case for 65537 (use -Dseed=X to set PRNG seed)
|
||||
* @author Andreas Sterbenz
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Random;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
|
||||
public class ModPow65537 {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// SunRsaSign uses BigInteger internally
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "SunRsaSign");
|
||||
kpg.initialize(new RSAKeyGenParameterSpec(512, BigInteger.valueOf(65537)));
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
testSigning(kp);
|
||||
|
||||
kpg.initialize(new RSAKeyGenParameterSpec(512, BigInteger.valueOf(65539)));
|
||||
kp = kpg.generateKeyPair();
|
||||
testSigning(kp);
|
||||
|
||||
kpg.initialize(new RSAKeyGenParameterSpec(512, BigInteger.valueOf(3)));
|
||||
kp = kpg.generateKeyPair();
|
||||
testSigning(kp);
|
||||
|
||||
// basic known answer test
|
||||
BigInteger base = new BigInteger("19058071224156864789844466979330892664777520457048234786139035643344145635582");
|
||||
BigInteger mod = new BigInteger("75554098474976067521257305210610421240510163914613117319380559667371251381587");
|
||||
BigInteger exp1 = BigInteger.valueOf(65537);
|
||||
BigInteger exp2 = BigInteger.valueOf(75537);
|
||||
BigInteger exp3 = new BigInteger("13456870775607312149");
|
||||
|
||||
BigInteger res1 = new BigInteger("5770048609366563851320890693196148833634112303472168971638730461010114147506");
|
||||
BigInteger res2 = new BigInteger("63446979364051087123350579021875958137036620431381329472348116892915461751531");
|
||||
BigInteger res3 = new BigInteger("39016891919893878823999350081191675846357272199067075794096200770872982089502");
|
||||
|
||||
if (base.modPow(exp1, mod).equals(res1) == false) {
|
||||
throw new Exception("Error using " + exp1);
|
||||
}
|
||||
if (base.modPow(exp2, mod).equals(res2) == false) {
|
||||
throw new Exception("Error using " + exp2);
|
||||
}
|
||||
if (base.modPow(exp3, mod).equals(res3) == false) {
|
||||
throw new Exception("Error using " + exp3);
|
||||
}
|
||||
|
||||
System.out.println("Passed");
|
||||
}
|
||||
|
||||
private static void testSigning(KeyPair kp) throws Exception {
|
||||
System.out.println(kp.getPublic());
|
||||
byte[] data = new byte[1024];
|
||||
Random random = RandomFactory.getRandom();
|
||||
random.nextBytes(data);
|
||||
|
||||
Signature sig = Signature.getInstance("SHA1withRSA", "SunRsaSign");
|
||||
sig.initSign(kp.getPrivate());
|
||||
sig.update(data);
|
||||
byte[] sigBytes = sig.sign();
|
||||
|
||||
sig.initVerify(kp.getPublic());
|
||||
sig.update(data);
|
||||
if (sig.verify(sigBytes) == false) {
|
||||
throw new Exception("signature verification failed");
|
||||
}
|
||||
System.out.println("OK");
|
||||
}
|
||||
|
||||
}
|
||||
85
test/jdk/java/math/BigInteger/ModPowPowersof2.java
Normal file
85
test/jdk/java/math/BigInteger/ModPowPowersof2.java
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 4098742
|
||||
@summary Test biginteger modpow method
|
||||
@author Michael McCloskey
|
||||
@run main/othervm ModPowPowersof2
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class tests to see if using modPow on a power
|
||||
* of two crashes the vm
|
||||
*
|
||||
*/
|
||||
public class ModPowPowersof2 {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
// Construct a command that runs the test in other vm
|
||||
String[] command = new String[4];
|
||||
int n = 0;
|
||||
|
||||
command[n++] = System.getProperty("java.home") + File.separator +
|
||||
"bin" + File.separator + "java";
|
||||
if (System.getProperty("java.class.path") != null) {
|
||||
command[n++] = "-classpath";
|
||||
command[n++] = System.getProperty("java.class.path");
|
||||
}
|
||||
|
||||
command[n++] = "ModPowPowersof2$ModTester";
|
||||
|
||||
// Exec another vm to run test in
|
||||
Process p = null;
|
||||
p = Runtime.getRuntime().exec(command);
|
||||
|
||||
// Read the result to determine if test failed
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(
|
||||
p.getInputStream()));
|
||||
String s;
|
||||
s = in.readLine();
|
||||
if (s == null)
|
||||
throw new RuntimeException("ModPow causes vm crash");
|
||||
|
||||
}
|
||||
|
||||
public static class ModTester {
|
||||
public static void main(String [] args) {
|
||||
BigInteger two = BigInteger.valueOf(2);
|
||||
BigInteger four = BigInteger.valueOf(4);
|
||||
|
||||
two.modPow(two, BigInteger.valueOf(4));
|
||||
two.modPow(two, BigInteger.valueOf(8));
|
||||
two.modPow(four, BigInteger.valueOf(8));
|
||||
|
||||
System.out.println("success");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
191
test/jdk/java/math/BigInteger/MutableBigIntegerShiftTests.java
Normal file
191
test/jdk/java/math/BigInteger/MutableBigIntegerShiftTests.java
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.test.lib.RandomFactory;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.math.MutableBigIntegerBox;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static java.math.MutableBigIntegerBox.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8336274
|
||||
* @summary Tests for correctness of MutableBigInteger.leftShift(int)
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.RandomFactory
|
||||
* @build java.base/java.math.MutableBigIntegerBox
|
||||
* @key randomness
|
||||
* @run junit MutableBigIntegerShiftTests
|
||||
*/
|
||||
public class MutableBigIntegerShiftTests {
|
||||
|
||||
private static final int ORDER_SMALL = 60;
|
||||
private static final int ORDER_MEDIUM = 100;
|
||||
|
||||
private static final Random random = RandomFactory.getRandom();
|
||||
|
||||
private static int[] orders() {
|
||||
return new int[] { ORDER_SMALL, ORDER_MEDIUM };
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("orders")
|
||||
public void shift(int order) {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
test(fetchNumber(order), random.nextInt(200));
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("pathTargetedCases")
|
||||
public void test(MutableBigIntegerBox x, int n) {
|
||||
leftShiftAssertions(x, n);
|
||||
}
|
||||
|
||||
private static Arguments[] pathTargetedCases() {
|
||||
return new Arguments[] {
|
||||
// intLen == 0
|
||||
Arguments.of(MutableBigIntegerBox.ZERO,
|
||||
random.nextInt(33)),
|
||||
// intLen != 0 && n <= leadingZeros
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { (int) random.nextLong(1L, 1L << 16) }),
|
||||
random.nextInt(1, 17)),
|
||||
// intLen != 0 && n > leadingZeros && nBits <= leadingZeros && value.length < newLen && nBits == 0
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { (int) random.nextLong(1L, 1L << 32) }),
|
||||
32),
|
||||
// intLen != 0 && n > leadingZeros && nBits <= leadingZeros && value.length < newLen && nBits != 0
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { (int) random.nextLong(1L, 1L << 16) }),
|
||||
32 + random.nextInt(1, 17)),
|
||||
// intLen != 0 && n > leadingZeros && nBits <= leadingZeros && value.length >= newLen && nBits == 0
|
||||
// && newOffset != offset
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { random.nextInt(), (int) random.nextLong(1L, 1L << 32) }, 1, 1),
|
||||
32),
|
||||
// intLen != 0 && n > leadingZeros && nBits <= leadingZeros && value.length >= newLen && nBits == 0
|
||||
// && newOffset == offset
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { (int) random.nextLong(1L, 1L << 32), random.nextInt() }, 0, 1),
|
||||
32),
|
||||
// intLen != 0 && n > leadingZeros && nBits <= leadingZeros && value.length >= newLen && nBits != 0
|
||||
// && newOffset != offset
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { random.nextInt(), (int) random.nextLong(1L, 1L << 16) }, 1, 1),
|
||||
32 + random.nextInt(1, 17)),
|
||||
// intLen != 0 && n > leadingZeros && nBits <= leadingZeros && value.length >= newLen && nBits != 0
|
||||
// && newOffset == offset
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { (int) random.nextLong(1L, 1L << 16), random.nextInt() }, 0, 1),
|
||||
32 + random.nextInt(1, 17)),
|
||||
// intLen != 0 && n > leadingZeros && nBits > leadingZeros && value.length < newLen
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { (int) random.nextLong(1L << 15, 1L << 32) }),
|
||||
random.nextInt(17, 32)),
|
||||
// intLen != 0 && n > leadingZeros && nBits > leadingZeros && value.length >= newLen && newOffset != offset
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { random.nextInt(), (int) random.nextLong(1L << 15, 1L << 32) }, 1, 1),
|
||||
random.nextInt(17, 32)),
|
||||
// intLen != 0 && n > leadingZeros && nBits > leadingZeros && value.length >= newLen && newOffset == offset
|
||||
Arguments.of(new MutableBigIntegerBox(new int[] { (int) random.nextLong(1L << 15, 1L << 32), random.nextInt() }, 0, 1),
|
||||
random.nextInt(17, 32)),
|
||||
};
|
||||
}
|
||||
|
||||
private static void leftShiftAssertions(MutableBigIntegerBox x, int n) {
|
||||
MutableBigIntegerBox xShifted = x.shiftLeft(n);
|
||||
assertEquals(x.multiply(new MutableBigIntegerBox(BigInteger.TWO.pow(n))), xShifted);
|
||||
assertEquals(x, xShifted.shiftRight(n));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a random or boundary-case number. This is designed to provide
|
||||
* a lot of numbers that will find failure points, such as max sized
|
||||
* numbers, empty MutableBigIntegers, etc.
|
||||
*
|
||||
* If order is less than 2, order is changed to 2.
|
||||
*/
|
||||
private static MutableBigIntegerBox fetchNumber(int order) {
|
||||
int numType = random.nextInt(8);
|
||||
MutableBigIntegerBox result = null;
|
||||
if (order < 2) order = 2;
|
||||
|
||||
int[] val;
|
||||
switch (numType) {
|
||||
case 0: // Empty
|
||||
result = MutableBigIntegerBox.ZERO;
|
||||
break;
|
||||
|
||||
case 1: // One
|
||||
result = MutableBigIntegerBox.ONE;
|
||||
break;
|
||||
|
||||
case 2: // All bits set in number
|
||||
int numInts = (order + 31) >> 5;
|
||||
int[] fullBits = new int[numInts];
|
||||
Arrays.fill(fullBits, -1);
|
||||
|
||||
fullBits[0] &= -1 >>> -order;
|
||||
result = new MutableBigIntegerBox(fullBits);
|
||||
break;
|
||||
|
||||
case 3: // One bit in number
|
||||
result = MutableBigIntegerBox.ONE.shiftLeft(random.nextInt(order));
|
||||
break;
|
||||
|
||||
case 4: // Random bit density
|
||||
val = new int[(order + 31) >> 5];
|
||||
int iterations = random.nextInt(order);
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
int bitIdx = random.nextInt(order);
|
||||
val[bitIdx >> 5] |= 1 << bitIdx;
|
||||
}
|
||||
result = new MutableBigIntegerBox(val);
|
||||
break;
|
||||
case 5: // Runs of consecutive ones and zeros
|
||||
result = ZERO;
|
||||
int remaining = order;
|
||||
int bit = random.nextInt(2);
|
||||
while (remaining > 0) {
|
||||
int runLength = Math.min(remaining, random.nextInt(order));
|
||||
result = result.shiftLeft(runLength);
|
||||
if (bit > 0)
|
||||
result = result.add(ONE.shiftLeft(runLength).subtract(ONE));
|
||||
remaining -= runLength;
|
||||
bit = 1 - bit;
|
||||
}
|
||||
break;
|
||||
case 6: // random bits with trailing space
|
||||
int len = random.nextInt((order + 31) >> 5) + 1;
|
||||
int offset = random.nextInt(len);
|
||||
val = new int[len << 1];
|
||||
for (int i = 0; i < val.length; i++)
|
||||
val[i] = random.nextInt();
|
||||
result = new MutableBigIntegerBox(val, offset, len);
|
||||
break;
|
||||
default: // random bits
|
||||
result = new MutableBigIntegerBox(new BigInteger(order, random));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
71
test/jdk/java/math/BigInteger/OperatorNpeTests.java
Normal file
71
test/jdk/java/math/BigInteger/OperatorNpeTests.java
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6365176
|
||||
* @summary Get NullPointerExceptions when expected
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import static java.math.BigInteger.*;
|
||||
|
||||
public class OperatorNpeTests {
|
||||
|
||||
public static void main(String... argv) {
|
||||
BigInteger[] specialValues = {ZERO, ONE, TEN};
|
||||
|
||||
for (BigInteger bd : specialValues) {
|
||||
BigInteger result;
|
||||
try {
|
||||
result = bd.multiply(null);
|
||||
throw new RuntimeException("Instead of NPE got " + result);
|
||||
} catch (NullPointerException npe) {
|
||||
; // Expected
|
||||
}
|
||||
|
||||
try {
|
||||
result = bd.divide(null);
|
||||
throw new RuntimeException("Instead of NPE got " + result);
|
||||
} catch (NullPointerException npe) {
|
||||
; // Expected
|
||||
}
|
||||
|
||||
try {
|
||||
result = bd.add(null);
|
||||
throw new RuntimeException("Instead of NPE got " + result);
|
||||
} catch (NullPointerException npe) {
|
||||
; // Expected
|
||||
}
|
||||
|
||||
try {
|
||||
result = bd.subtract(null);
|
||||
throw new RuntimeException("Instead of NPE got " + result);
|
||||
} catch (NullPointerException npe) {
|
||||
; // Expected
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
252
test/jdk/java/math/BigInteger/PrimeTest.java
Normal file
252
test/jdk/java/math/BigInteger/PrimeTest.java
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.RandomFactory
|
||||
* @run main PrimeTest
|
||||
* @bug 8026236 8074460 8078672 8294593
|
||||
* @summary test primality verification methods in BigInteger (use -Dseed=X to set PRNG seed)
|
||||
* @author bpb
|
||||
* @key randomness
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
import java.util.SplittableRandom;
|
||||
import java.util.TreeSet;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
import static java.util.stream.Collectors.toCollection;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
public class PrimeTest {
|
||||
|
||||
private static final int DEFAULT_UPPER_BOUND = 1299709; // 100000th prime
|
||||
private static final int DEFAULT_CERTAINTY = 100;
|
||||
private static final int NUM_NON_PRIMES = 10000;
|
||||
|
||||
/**
|
||||
* Run the test.
|
||||
*
|
||||
* @param args The parameters.
|
||||
* @throws Exception on failure
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Prepare arguments
|
||||
int upperBound = args.length > 0 ? Integer.valueOf(args[0]) : DEFAULT_UPPER_BOUND;
|
||||
int certainty = args.length > 1 ? Integer.valueOf(args[1]) : DEFAULT_CERTAINTY;
|
||||
boolean parallel = args.length > 2 ? Boolean.valueOf(args[2]) : true;
|
||||
|
||||
// Echo parameter settings
|
||||
System.out.println("Upper bound = " + upperBound
|
||||
+ "\nCertainty = " + certainty
|
||||
+ "\nParallel = " + parallel);
|
||||
|
||||
// Get primes through specified bound (inclusive) and Integer.MAX_VALUE
|
||||
NavigableSet<BigInteger> primes = getPrimes(upperBound);
|
||||
|
||||
// Check whether known primes are identified as such
|
||||
boolean primeTest = checkPrime(primes, certainty, parallel);
|
||||
System.out.println("Prime test result: " + (primeTest ? "SUCCESS" : "FAILURE"));
|
||||
if (!primeTest) {
|
||||
System.err.println("Prime test failed");
|
||||
}
|
||||
|
||||
// Check whether known non-primes are not identified as primes
|
||||
boolean nonPrimeTest = checkNonPrime(primes, certainty);
|
||||
System.out.println("Non-prime test result: " + (nonPrimeTest ? "SUCCESS" : "FAILURE"));
|
||||
|
||||
boolean mersennePrimeTest = checkMersennePrimes(certainty);
|
||||
System.out.println("Mersenne test result: " + (mersennePrimeTest ? "SUCCESS" : "FAILURE"));
|
||||
|
||||
if (!primeTest || !nonPrimeTest || !mersennePrimeTest) {
|
||||
throw new Exception("PrimeTest FAILED!");
|
||||
}
|
||||
|
||||
if (!checkHugeFails()) {
|
||||
throw new Exception("Primality test on huge integer should fail but succeeded");
|
||||
}
|
||||
|
||||
System.out.println("PrimeTest succeeded!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code BitSet} wherein a set bit indicates the corresponding
|
||||
* index plus 2 is prime. That is, if bit N is set, then the integer N + 2
|
||||
* is prime. The values 0 and 1 are intentionally excluded. See the
|
||||
* <a
|
||||
* href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Algorithm_description">
|
||||
* Sieve of Eratosthenes</a> algorithm description for more information.
|
||||
*
|
||||
* @param upperBound The maximum prime to allow
|
||||
* @return bits indicating which indexes represent primes
|
||||
*/
|
||||
private static BitSet createPrimes(int upperBound) {
|
||||
int nbits = upperBound - 1;
|
||||
BitSet bs = new BitSet(nbits);
|
||||
for (int p = 2; p * p < upperBound;) {
|
||||
for (int i = p * p; i < nbits + 2; i += p) {
|
||||
bs.set(i - 2, true);
|
||||
}
|
||||
do {
|
||||
++p;
|
||||
} while (p > 1 && bs.get(p - 2));
|
||||
}
|
||||
bs.flip(0, nbits);
|
||||
return bs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the primes up to the specified bound (inclusive) into a
|
||||
* {@code NavigableSet}, appending the prime {@code Integer.MAX_VALUE}.
|
||||
*
|
||||
* @param upperBound The maximum prime to allow
|
||||
* @return a set of primes
|
||||
*/
|
||||
private static NavigableSet<BigInteger> getPrimes(int upperBound) {
|
||||
BitSet bs = createPrimes(upperBound);
|
||||
NavigableSet<BigInteger> primes = bs.stream()
|
||||
.mapToObj(p -> BigInteger.valueOf(p + 2))
|
||||
.collect(toCollection(TreeSet::new));
|
||||
primes.add(BigInteger.valueOf(Integer.MAX_VALUE));
|
||||
System.out.println(String.format("Created %d primes", primes.size()));
|
||||
return primes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether the fraction of probable primes detected is at least 1 -
|
||||
* 1/2^certainty.
|
||||
*
|
||||
* @return true if and only if the test succeeds
|
||||
*/
|
||||
private static boolean checkPrime(Set<BigInteger> primes,
|
||||
int certainty,
|
||||
boolean parallel) {
|
||||
long probablePrimes = (parallel ? primes.parallelStream() : primes.stream())
|
||||
.filter(bi -> bi.isProbablePrime(certainty))
|
||||
.count();
|
||||
|
||||
// N = certainty / 2
|
||||
// Success if p/t >= 1 - 1/4^N
|
||||
// or (p/t)*4^N >= 4^N - 1
|
||||
// or p*4^N >= t*(4^N - 1)
|
||||
BigInteger p = BigInteger.valueOf(probablePrimes);
|
||||
BigInteger t = BigInteger.valueOf(primes.size());
|
||||
BigInteger fourToTheC = BigInteger.valueOf(4).pow(certainty / 2);
|
||||
BigInteger fourToTheCMinusOne = fourToTheC.subtract(BigInteger.ONE);
|
||||
BigInteger left = p.multiply(fourToTheC);
|
||||
BigInteger right = t.multiply(fourToTheCMinusOne);
|
||||
|
||||
if (left.compareTo(right) < 0) {
|
||||
System.err.println("Probable prime certainty test failed");
|
||||
}
|
||||
|
||||
return left.compareTo(right) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether all {@code BigInteger}s in the tested range for which
|
||||
* {@code isProbablePrime()} returns {@code false} are <i>not</i>
|
||||
* prime numbers.
|
||||
*
|
||||
* @return true if and only if the test succeeds
|
||||
*/
|
||||
private static boolean checkNonPrime(NavigableSet<BigInteger> primes,
|
||||
int certainty) {
|
||||
int maxPrime = DEFAULT_UPPER_BOUND;
|
||||
try {
|
||||
maxPrime = primes.last().intValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
// ignore it
|
||||
}
|
||||
|
||||
// Create a list of non-prime BigIntegers.
|
||||
SplittableRandom splitRandom = RandomFactory.getSplittableRandom();
|
||||
List<BigInteger> nonPrimeBigInts = (splitRandom)
|
||||
.ints(NUM_NON_PRIMES, 2, maxPrime).mapToObj(BigInteger::valueOf)
|
||||
.filter(b -> !b.isProbablePrime(certainty)).collect(toList());
|
||||
|
||||
// If there are any non-probable primes also in the primes list then fail.
|
||||
boolean failed = nonPrimeBigInts.stream().anyMatch(primes::contains);
|
||||
|
||||
// In the event, print which purported non-primes were actually prime.
|
||||
if (failed) {
|
||||
for (BigInteger bigInt : nonPrimeBigInts) {
|
||||
if (primes.contains(bigInt)) {
|
||||
System.err.println("Prime value thought to be non-prime: " + bigInt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether a specified subset of Mersenne primes are correctly
|
||||
* identified as being prime. See
|
||||
* <a href="https://en.wikipedia.org/wiki/Mersenne_prime">Mersenne prime</a>
|
||||
* for more information.
|
||||
*
|
||||
* @return true if and only if the test succeeds
|
||||
*/
|
||||
private static boolean checkMersennePrimes(int certainty) {
|
||||
int[] MERSENNE_EXPONENTS = {
|
||||
2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107, 127, 521, 607, 1279, 2203,
|
||||
2281, 3217, 4253, // uncomment remaining array elements to make this test run a long time
|
||||
/* 4423, 9689, 9941, 11213, 19937, 21701, 23209, 44497,
|
||||
86243, 110503, 132049, 216091, 756839, 859433, 1257787, 1398269,
|
||||
2976221, 3021377, 6972593, 13466917, 20996011, 24036583, 25964951,
|
||||
30402457, 32582657, 37156667, 42643801, 43112609, 57885161 */
|
||||
};
|
||||
System.out.println("Checking first "+MERSENNE_EXPONENTS.length+" Mersenne primes");
|
||||
|
||||
boolean result = true;
|
||||
for (int n : MERSENNE_EXPONENTS) {
|
||||
BigInteger mp = BigInteger.ONE.shiftLeft(n).subtract(BigInteger.ONE);
|
||||
if (!mp.isProbablePrime(certainty)) {
|
||||
System.err.println("Mp with p = "+n+" not classified as prime");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean checkHugeFails() {
|
||||
try {
|
||||
// huge odd integer
|
||||
BigInteger a = BigInteger.ONE.shiftLeft(500_000_000 + 1)
|
||||
.setBit(0);
|
||||
a.isProbablePrime(1);
|
||||
// not expected to reach here
|
||||
return false;
|
||||
} catch (ArithmeticException e) {
|
||||
// this is the expected behavior
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
109
test/jdk/java/math/BigInteger/PrimitiveConversionTests.java
Normal file
109
test/jdk/java/math/BigInteger/PrimitiveConversionTests.java
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static java.math.BigInteger.ONE;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 7131192
|
||||
* @summary This test ensures that BigInteger.floatValue() and
|
||||
* BigInteger.doubleValue() behave correctly.
|
||||
* @author Louis Wasserman
|
||||
*/
|
||||
public class PrimitiveConversionTests {
|
||||
static final List<BigInteger> ALL_BIGINTEGER_CANDIDATES;
|
||||
|
||||
static {
|
||||
List<BigInteger> samples = new ArrayList<>();
|
||||
// Now add values near 2^N for lots of values of N.
|
||||
for (int exponent : Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 31, 32, 33,
|
||||
34, 62, 63, 64, 65, 71, 72, 73, 79, 80, 81, 255, 256, 257, 511,
|
||||
512, 513, Double.MAX_EXPONENT - 1, Double.MAX_EXPONENT,
|
||||
Double.MAX_EXPONENT + 1, 2000, 2001, 2002)) {
|
||||
BigInteger x = ONE.shiftLeft(exponent);
|
||||
for (BigInteger y : Arrays.asList(x, x.add(ONE), x.subtract(ONE))) {
|
||||
samples.add(y);
|
||||
samples.add(y.negate());
|
||||
}
|
||||
}
|
||||
|
||||
Random rng = new Random(1234567);
|
||||
for (int i = 0; i < 2000; i++) {
|
||||
samples.add(new BigInteger(rng.nextInt(2000), rng));
|
||||
}
|
||||
|
||||
ALL_BIGINTEGER_CANDIDATES = Collections.unmodifiableList(samples);
|
||||
}
|
||||
|
||||
public static int testDoubleValue() {
|
||||
System.out.println("--- testDoubleValue ---");
|
||||
int failures = 0;
|
||||
for (BigInteger big : ALL_BIGINTEGER_CANDIDATES) {
|
||||
double expected = Double.parseDouble(big.toString());
|
||||
double actual = big.doubleValue();
|
||||
|
||||
// should be bitwise identical
|
||||
if (Double.doubleToRawLongBits(expected) != Double
|
||||
.doubleToRawLongBits(actual)) {
|
||||
System.out.format("big: %s, expected: %f, actual: %f%n",
|
||||
big, expected, actual);
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static int testFloatValue() {
|
||||
System.out.println("--- testFloatValue ---");
|
||||
int failures = 0;
|
||||
for (BigInteger big : ALL_BIGINTEGER_CANDIDATES) {
|
||||
float expected = Float.parseFloat(big.toString());
|
||||
float actual = big.floatValue();
|
||||
|
||||
// should be bitwise identical
|
||||
if (Float.floatToRawIntBits(expected) != Float
|
||||
.floatToRawIntBits(actual)) {
|
||||
System.out.format("big: %s, expected: %f, actual: %f%n",
|
||||
big, expected, actual);
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int failures = testDoubleValue();
|
||||
failures += testFloatValue();
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures
|
||||
+ " failures while testing primitive conversions.");
|
||||
}
|
||||
}
|
||||
}
|
||||
48
test/jdk/java/math/BigInteger/ProbablePrime.java
Normal file
48
test/jdk/java/math/BigInteger/ProbablePrime.java
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4654323
|
||||
* @summary Tests functionality of isProbablePrime(Integer.MAX_VALUE)
|
||||
*/
|
||||
import java.math.*;
|
||||
|
||||
public class ProbablePrime {
|
||||
public static void main(String [] argv) {
|
||||
BigInteger num = new BigInteger("4");
|
||||
int certainties[] = {-1, 0, 1, 2, 100, Integer.MAX_VALUE-1,
|
||||
Integer.MAX_VALUE};
|
||||
boolean expectations[] = {true, true, false, false, false,
|
||||
false, false};
|
||||
|
||||
for(int i = 0; i < certainties.length; i++) {
|
||||
boolean b;
|
||||
if((b=num.isProbablePrime(certainties[i])) !=
|
||||
expectations[i])
|
||||
throw new RuntimeException("Unexpected answer " + b +
|
||||
" for certainty " +
|
||||
certainties[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
141
test/jdk/java/math/BigInteger/SerializationTests.java
Normal file
141
test/jdk/java/math/BigInteger/SerializationTests.java
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8282252
|
||||
* @summary Verify BigInteger objects are serialized properly.
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class SerializationTests {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
checkBigIntegerSerialRoundTrip();
|
||||
checkBigIntegerSubSerialRoundTrip();
|
||||
}
|
||||
|
||||
private static void checkSerialForm(BigInteger bi) throws Exception {
|
||||
checkSerialForm0(bi);
|
||||
checkSerialForm0(bi.negate());
|
||||
}
|
||||
|
||||
private static void checkSerialForm0(BigInteger bi) throws Exception {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
try(ObjectOutputStream oos = new ObjectOutputStream(bos)) {
|
||||
oos.writeObject(bi);
|
||||
oos.flush();
|
||||
}
|
||||
|
||||
ObjectInputStream ois = new
|
||||
ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
|
||||
BigInteger tmp = (BigInteger)ois.readObject();
|
||||
|
||||
if (!bi.equals(tmp) ||
|
||||
bi.hashCode() != tmp.hashCode() ||
|
||||
bi.getClass() != tmp.getClass() ||
|
||||
// For extra measure, directly test equality of components
|
||||
bi.signum() != tmp.signum() ||
|
||||
!Arrays.equals(bi.toByteArray(), (tmp.toByteArray())) ) {
|
||||
System.err.print(" original : " + bi);
|
||||
System.err.println(" (hash: 0x" + Integer.toHexString(bi.hashCode()) + ")");
|
||||
System.err.print("serialized : " + tmp);
|
||||
System.err.println(" (hash: 0x" + Integer.toHexString(tmp.hashCode()) + ")");
|
||||
throw new RuntimeException("Bad serial roundtrip");
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkBigIntegerSerialRoundTrip() throws Exception {
|
||||
var values =
|
||||
List.of(BigInteger.ZERO,
|
||||
BigInteger.ONE,
|
||||
BigInteger.TWO,
|
||||
BigInteger.TEN,
|
||||
BigInteger.valueOf(100),
|
||||
BigInteger.valueOf(Integer.MAX_VALUE),
|
||||
BigInteger.valueOf(Long.MAX_VALUE-1),
|
||||
new BigInteger("9223372036854775808")); // Long.MAX_VALUE + 1
|
||||
|
||||
for(BigInteger value : values) {
|
||||
checkSerialForm(value);
|
||||
}
|
||||
}
|
||||
|
||||
// Subclass with specialized toString output
|
||||
private static class BigIntegerSub extends BigInteger {
|
||||
public BigIntegerSub(BigInteger bi) {
|
||||
super(bi.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Arrays.toString(toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
// Subclass defining a serialVersionUID
|
||||
private static class BigIntegerSubSVUID extends BigInteger {
|
||||
@java.io.Serial
|
||||
private static long serialVesionUID = 0x0123_4567_89ab_cdefL;
|
||||
|
||||
public BigIntegerSubSVUID(BigInteger bi) {
|
||||
super(bi.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Arrays.toString(toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
// Subclass defining writeReplace
|
||||
private static class BigIntegerSubWR extends BigInteger {
|
||||
public BigIntegerSubWR(BigInteger bi) {
|
||||
super(bi.toByteArray());
|
||||
}
|
||||
|
||||
// Just return this; could use a serial proxy instead
|
||||
@java.io.Serial
|
||||
private Object writeReplace() throws ObjectStreamException {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void checkBigIntegerSubSerialRoundTrip() throws Exception {
|
||||
var values = List.of(BigInteger.ZERO,
|
||||
BigInteger.ONE,
|
||||
BigInteger.TEN,
|
||||
new BigInteger("9223372036854775808")); // Long.MAX_VALUE + 1
|
||||
|
||||
for(var value : values) {
|
||||
checkSerialForm(new BigIntegerSub(value));
|
||||
checkSerialForm(new BigIntegerSubSVUID(value));
|
||||
checkSerialForm(new BigIntegerSubWR(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
89
test/jdk/java/math/BigInteger/StringConstructor.java
Normal file
89
test/jdk/java/math/BigInteger/StringConstructor.java
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4489146 5017980
|
||||
* @summary tests String constructors of BigInteger
|
||||
*/
|
||||
import java.math.*;
|
||||
|
||||
public class StringConstructor {
|
||||
|
||||
|
||||
public static void main(String [] argv) {
|
||||
// Good strings
|
||||
constructWithoutError("0", 0L);
|
||||
constructWithoutError("000000000000000000", 0L);
|
||||
constructWithoutError("1", 1L);
|
||||
constructWithoutError("-1", -1L);
|
||||
constructWithoutError("+1", +1L);
|
||||
constructWithoutError( "123456789123456789", 123456789123456789L);
|
||||
constructWithoutError("+123456789123456789", 123456789123456789L);
|
||||
constructWithoutError("-123456789123456789", -123456789123456789L);
|
||||
constructWithoutError(Integer.toString(Integer.MIN_VALUE),
|
||||
(long)Integer.MIN_VALUE);
|
||||
constructWithoutError(Integer.toString(Integer.MAX_VALUE),
|
||||
(long)Integer.MAX_VALUE);
|
||||
constructWithoutError(Long.toString(Long.MIN_VALUE),
|
||||
Long.MIN_VALUE);
|
||||
constructWithoutError(Long.toString(Long.MAX_VALUE),
|
||||
Long.MAX_VALUE);
|
||||
|
||||
// Bad strings
|
||||
constructWithError("");
|
||||
constructWithError("-");
|
||||
constructWithError("+");
|
||||
constructWithError("--");
|
||||
constructWithError("++");
|
||||
constructWithError("-000-0");
|
||||
constructWithError("+000+0");
|
||||
constructWithError("+000-0");
|
||||
constructWithError("--1234567890");
|
||||
constructWithError("++1234567890");
|
||||
constructWithError("-0-12345678");
|
||||
constructWithError("+0+12345678");
|
||||
constructWithError("--12345678-12345678-12345678");
|
||||
constructWithError("++12345678+12345678+12345678");
|
||||
constructWithError("12345-");
|
||||
constructWithError("12345+");
|
||||
}
|
||||
|
||||
// this method adapted from ../BigDecimal/StringConstructor.java
|
||||
private static void constructWithError(String badString) {
|
||||
try {
|
||||
BigInteger bi = new BigInteger(badString);
|
||||
throw new RuntimeException(badString + " accepted");
|
||||
} catch(NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
private static void constructWithoutError(String goodString, long value) {
|
||||
BigInteger bi = new BigInteger(goodString);
|
||||
if(bi.longValue() != value) {
|
||||
System.err.printf("From ``%s'' expected %d, got %s.\n", goodString, value, bi);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
193
test/jdk/java/math/BigInteger/TestValueExact.java
Normal file
193
test/jdk/java/math/BigInteger/TestValueExact.java
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6371401
|
||||
* @summary Tests of fooValueExact methods
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class TestValueExact {
|
||||
public static void main(String... args) {
|
||||
int errors = 0;
|
||||
|
||||
errors += testLongValueExact();
|
||||
errors += testIntValueExact();
|
||||
errors += testShortValueExact();
|
||||
errors += testByteValueExact();
|
||||
|
||||
if (errors > 0)
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
private static int testLongValueExact() {
|
||||
int errors = 0;
|
||||
BigInteger[] inRange = {
|
||||
BigInteger.valueOf(Long.MIN_VALUE),
|
||||
BigInteger.ZERO,
|
||||
BigInteger.valueOf(Long.MAX_VALUE)
|
||||
};
|
||||
|
||||
BigInteger[] outOfRange = {
|
||||
BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.ONE),
|
||||
BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE)
|
||||
};
|
||||
|
||||
for (BigInteger bi : inRange) {
|
||||
if (bi.longValueExact() != bi.longValue()) {
|
||||
System.err.println("Mismatching int conversion for " + bi);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
for (BigInteger bi : outOfRange) {
|
||||
try {
|
||||
long value = bi.longValueExact();
|
||||
System.err.println("Failed to get expected exception on " +
|
||||
bi + " got " + value);
|
||||
errors++;
|
||||
} catch(ArithmeticException ae) {
|
||||
; // Expected
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testIntValueExact() {
|
||||
int errors = 0;
|
||||
BigInteger[] inRange = {
|
||||
BigInteger.valueOf(Integer.MIN_VALUE),
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ONE,
|
||||
BigInteger.TEN,
|
||||
BigInteger.valueOf(Integer.MAX_VALUE)
|
||||
};
|
||||
|
||||
BigInteger[] outOfRange = {
|
||||
BigInteger.valueOf((long)Integer.MIN_VALUE - 1),
|
||||
BigInteger.valueOf((long)Integer.MAX_VALUE + 1)
|
||||
};
|
||||
|
||||
for (BigInteger bi : inRange) {
|
||||
if (bi.intValueExact() != bi.intValue()) {
|
||||
System.err.println("Mismatching int conversion for " + bi);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
for (BigInteger bi : outOfRange) {
|
||||
try {
|
||||
int value = bi.intValueExact();
|
||||
System.err.println("Failed to get expected exception on " +
|
||||
bi + " got " + value);
|
||||
errors++;
|
||||
} catch(ArithmeticException ae) {
|
||||
; // Expected
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testShortValueExact() {
|
||||
int errors = 0;
|
||||
BigInteger[] inRange = {
|
||||
BigInteger.valueOf(Short.MIN_VALUE),
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ONE,
|
||||
BigInteger.TEN,
|
||||
BigInteger.valueOf(Short.MAX_VALUE)
|
||||
};
|
||||
|
||||
BigInteger[] outOfRange = {
|
||||
BigInteger.valueOf((long)Integer.MIN_VALUE - 1),
|
||||
BigInteger.valueOf((long)Integer.MIN_VALUE),
|
||||
BigInteger.valueOf( (int)Short.MIN_VALUE - 1),
|
||||
BigInteger.valueOf( (int)Short.MAX_VALUE + 1),
|
||||
BigInteger.valueOf((long)Integer.MAX_VALUE),
|
||||
BigInteger.valueOf((long)Integer.MAX_VALUE + 1)
|
||||
};
|
||||
|
||||
for (BigInteger bi : inRange) {
|
||||
if (bi.shortValueExact() != bi.shortValue()) {
|
||||
System.err.println("Mismatching short conversion for " + bi);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
for (BigInteger bi : outOfRange) {
|
||||
try {
|
||||
int value = bi.shortValueExact();
|
||||
System.err.println("Failed to get expected exception on " +
|
||||
bi + " got " + value);
|
||||
errors++;
|
||||
} catch(ArithmeticException ae) {
|
||||
; // Expected
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testByteValueExact() {
|
||||
int errors = 0;
|
||||
BigInteger[] inRange = {
|
||||
BigInteger.valueOf(Byte.MIN_VALUE),
|
||||
BigInteger.valueOf(0),
|
||||
BigInteger.ONE,
|
||||
BigInteger.TEN,
|
||||
BigInteger.valueOf(Byte.MAX_VALUE)
|
||||
};
|
||||
|
||||
BigInteger[] outOfRange = {
|
||||
BigInteger.valueOf((long)Integer.MIN_VALUE - 1),
|
||||
BigInteger.valueOf((long)Integer.MIN_VALUE),
|
||||
BigInteger.valueOf( (int)Short.MIN_VALUE - 1),
|
||||
BigInteger.valueOf( (int)Short.MIN_VALUE),
|
||||
BigInteger.valueOf( (int)Byte.MIN_VALUE - 1),
|
||||
BigInteger.valueOf( (int)Byte.MAX_VALUE + 1),
|
||||
BigInteger.valueOf( (int)Short.MAX_VALUE + 1),
|
||||
BigInteger.valueOf( (int)Short.MAX_VALUE),
|
||||
BigInteger.valueOf((long)Integer.MAX_VALUE),
|
||||
BigInteger.valueOf((long)Integer.MAX_VALUE + 1)
|
||||
};
|
||||
|
||||
for (BigInteger bi : inRange) {
|
||||
if (bi.byteValueExact() != bi.byteValue()) {
|
||||
System.err.println("Mismatching byte conversion for " + bi);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
for (BigInteger bi : outOfRange) {
|
||||
try {
|
||||
int value = bi.byteValueExact();
|
||||
System.err.println("Failed to get expected exception on " +
|
||||
bi + " got " + value);
|
||||
errors++;
|
||||
} catch(ArithmeticException ae) {
|
||||
; // Expected
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
57
test/jdk/java/math/BigInteger/UnicodeConstructor.java
Normal file
57
test/jdk/java/math/BigInteger/UnicodeConstructor.java
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4040456
|
||||
* @summary Test biginteger constructor with i18n string
|
||||
*/
|
||||
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* This class tests to see if creating a biginteger with an
|
||||
* unicode japanese zero and one succeeds
|
||||
*
|
||||
*/
|
||||
public class UnicodeConstructor {
|
||||
|
||||
public static void main(String args[]) {
|
||||
|
||||
try {
|
||||
// the code for japanese zero
|
||||
BigInteger b1 = new BigInteger("\uff10");
|
||||
System.err.println(b1.toString());
|
||||
|
||||
// Japanese 1010
|
||||
BigInteger b2 = new BigInteger("\uff11\uff10\uff11\uff10");
|
||||
System.err.println(b2.toString());
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new RuntimeException(
|
||||
"BigInteger is not accepting unicode initializers.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.math;
|
||||
|
||||
public class Accessor {
|
||||
|
||||
public static int[] mag(BigInteger bi) {
|
||||
return bi.mag;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.math;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A class for tests.
|
||||
*/
|
||||
public class MutableBigIntegerBox {
|
||||
|
||||
/**
|
||||
* Constant zero
|
||||
*/
|
||||
public static final MutableBigIntegerBox ZERO = new MutableBigIntegerBox(new MutableBigInteger());
|
||||
|
||||
/**
|
||||
* Constant one
|
||||
*/
|
||||
public static final MutableBigIntegerBox ONE = new MutableBigIntegerBox(MutableBigInteger.ONE);
|
||||
|
||||
/**
|
||||
* Constant two
|
||||
*/
|
||||
public static final MutableBigIntegerBox TWO = new MutableBigIntegerBox(new MutableBigInteger(2));
|
||||
|
||||
private MutableBigInteger val;
|
||||
|
||||
MutableBigIntegerBox(MutableBigInteger val) {
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct MutableBigIntegerBox from magnitude, starting from
|
||||
* offset and with a length of intLen ints.
|
||||
* The value is normalized.
|
||||
* @param mag the magnitude
|
||||
* @param offset the offset where the value starts
|
||||
* @param intLen the length of the value, in int words.
|
||||
*/
|
||||
public MutableBigIntegerBox(int[] mag, int offset, int intLen) {
|
||||
this(new MutableBigInteger(mag));
|
||||
val.offset = offset;
|
||||
val.intLen = intLen;
|
||||
val.normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct MutableBigIntegerBox from magnitude.
|
||||
* The value is normalized.
|
||||
* @param mag the magnitude
|
||||
*/
|
||||
public MutableBigIntegerBox(int[] mag) {
|
||||
this(mag, 0, mag.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct MutableBigIntegerBox from BigInteger val
|
||||
* @param val the value
|
||||
*/
|
||||
public MutableBigIntegerBox(BigInteger val) {
|
||||
this(val.mag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bit length of this MutableBigInteger value
|
||||
* @return the bit length of this MutableBigInteger value
|
||||
*/
|
||||
public long bitLength() {
|
||||
return val.bitLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code this << n}
|
||||
* @return {@code this << n}
|
||||
* @param n the shift
|
||||
*/
|
||||
public MutableBigIntegerBox shiftLeft(int n) {
|
||||
MutableBigIntegerBox res = new MutableBigIntegerBox(val.value.clone(), val.offset, val.intLen);
|
||||
res.val.safeLeftShift(n);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code this >> n}
|
||||
* @return {@code this >> n}
|
||||
* @param n the shift
|
||||
*/
|
||||
public MutableBigIntegerBox shiftRight(int n) {
|
||||
MutableBigInteger res = new MutableBigInteger(val);
|
||||
res.safeRightShift(n);
|
||||
return new MutableBigIntegerBox(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this + addend
|
||||
* @return this + addend
|
||||
* @param addend the addend
|
||||
*/
|
||||
public MutableBigIntegerBox add(MutableBigIntegerBox addend) {
|
||||
MutableBigInteger res = new MutableBigInteger(val);
|
||||
res.add(addend.val);
|
||||
return new MutableBigIntegerBox(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this - subtraend
|
||||
* @return this - subtraend
|
||||
* @param subtraend the subtraend
|
||||
*/
|
||||
public MutableBigIntegerBox subtract(MutableBigIntegerBox subtraend) {
|
||||
MutableBigInteger res = new MutableBigInteger(val);
|
||||
res.subtract(subtraend.val);
|
||||
return new MutableBigIntegerBox(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this * multiplier
|
||||
* @return this * multiplier
|
||||
* @param multiplier the multiplier
|
||||
*/
|
||||
public MutableBigIntegerBox multiply(MutableBigIntegerBox multiplier) {
|
||||
MutableBigInteger res = new MutableBigInteger();
|
||||
if (!(val.isZero() || multiplier.val.isZero()))
|
||||
val.multiply(multiplier.val, res);
|
||||
|
||||
return new MutableBigIntegerBox(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the magnitude of two MutableBigIntegers. Returns -1, 0 or 1
|
||||
* as this is numerically less than, equal to, or greater than {@code b}.
|
||||
* @return -1, 0 or 1 as this is numerically less than, equal to, or
|
||||
* greater than {@code b}.
|
||||
* @param b the value to compare
|
||||
*/
|
||||
public int compare(MutableBigIntegerBox b) {
|
||||
return val.compare(b.val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this MutableBigIntegerBox with the specified Object for equality.
|
||||
*
|
||||
* @param x Object to which this MutableBigIntegerBox is to be compared.
|
||||
* @return {@code true} if and only if the specified Object is a
|
||||
* MutableBigIntegerBox whose value is numerically equal to this MutableBigIntegerBox.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object x) {
|
||||
return (x instanceof MutableBigIntegerBox xInt)
|
||||
&& Arrays.equals(val.value, val.offset, val.offset + val.intLen,
|
||||
xInt.val.value, xInt.val.offset, xInt.val.offset + xInt.val.intLen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return val.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8022780
|
||||
* @summary Test division of large values
|
||||
* @requires (sun.arch.data.model == "64" & os.maxMemory > 8g)
|
||||
* @run main/othervm -Xshare:off -Xmx8g DivisionOverflow
|
||||
* @author Dmitry Nadezhin
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class DivisionOverflow {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
BigInteger a = BigInteger.ONE.shiftLeft(2147483646);
|
||||
BigInteger b = BigInteger.ONE.shiftLeft(1568);
|
||||
BigInteger[] qr = a.divideAndRemainder(b);
|
||||
BigInteger q = qr[0];
|
||||
BigInteger r = qr[1];
|
||||
if (!r.equals(BigInteger.ZERO)) {
|
||||
throw new RuntimeException("Incorrect signum() of remainder " + r.signum());
|
||||
}
|
||||
if (q.bitLength() != 2147482079) {
|
||||
throw new RuntimeException("Incorrect bitLength() of quotient " + q.bitLength());
|
||||
}
|
||||
System.out.println("Division of large values passed without overflow.");
|
||||
} catch (OutOfMemoryError e) {
|
||||
// possible
|
||||
System.err.println("DivisionOverflow skipped: OutOfMemoryError");
|
||||
System.err.println("Run jtreg with -javaoption:-Xmx8g");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8021204
|
||||
* @summary Test constructor BigInteger(String val, int radix) on very long string
|
||||
* @requires (sun.arch.data.model == "64" & os.maxMemory > 8g)
|
||||
* @run main/othervm -Xshare:off -Xmx8g StringConstructorOverflow
|
||||
* @author Dmitry Nadezhin
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class StringConstructorOverflow {
|
||||
|
||||
// String with hexadecimal value pow(2,pow(2,34))+1
|
||||
private static String makeLongHexString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('1');
|
||||
for (int i = 0; i < (1 << 30) - 1; i++) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append('1');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
BigInteger bi = new BigInteger(makeLongHexString(), 16);
|
||||
if (bi.compareTo(BigInteger.ONE) <= 0) {
|
||||
throw new RuntimeException("Incorrect result " + bi.toString());
|
||||
}
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
System.out.println("Overflow is reported by ArithmeticException, as expected");
|
||||
} catch (OutOfMemoryError e) {
|
||||
// possible
|
||||
System.err.println("StringConstructorOverflow skipped: OutOfMemoryError");
|
||||
System.err.println("Run jtreg with -javaoption:-Xmx8g");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,685 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6910473 8021204 8021203 9005933 8074460 8078672
|
||||
* @summary Test range of BigInteger values (use -Dseed=X to set PRNG seed)
|
||||
* @library /test/lib
|
||||
* @requires (sun.arch.data.model == "64" & os.maxMemory >= 10g)
|
||||
* @run main/timeout=180/othervm -Xmx8g -XX:+CompactStrings SymmetricRangeTests
|
||||
* @author Dmitry Nadezhin
|
||||
* @key randomness
|
||||
*/
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Random;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
|
||||
public class SymmetricRangeTests {
|
||||
|
||||
private static final BigInteger MAX_VALUE = makeMaxValue();
|
||||
private static final BigInteger MIN_VALUE = MAX_VALUE.negate();
|
||||
|
||||
private static final Random RANDOM = RandomFactory.getRandom();
|
||||
|
||||
private static BigInteger makeMaxValue() {
|
||||
byte[] ba = new byte[1 << 28];
|
||||
Arrays.fill(ba, (byte) 0xFF);
|
||||
ba[0] = (byte) 0x7F;
|
||||
return new BigInteger(ba);
|
||||
}
|
||||
|
||||
private static void check(String msg, BigInteger actual, BigInteger expected) {
|
||||
if (!actual.equals(expected)) {
|
||||
throw new RuntimeException(msg + ".bitLength()=" + actual.bitLength());
|
||||
}
|
||||
}
|
||||
|
||||
private static void check(String msg, double actual, double expected) {
|
||||
if (actual != expected) {
|
||||
throw new RuntimeException(msg + "=" + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private static void check(String msg, float actual, float expected) {
|
||||
if (actual != expected) {
|
||||
throw new RuntimeException(msg + "=" + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private static void check(String msg, long actual, long expected) {
|
||||
if (actual != expected) {
|
||||
throw new RuntimeException(msg + "=" + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private static void check(String msg, int actual, int expected) {
|
||||
if (actual != expected) {
|
||||
throw new RuntimeException(msg + "=" + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testOverflowInMakePositive() {
|
||||
System.out.println("Testing overflow in BigInteger.makePositive");
|
||||
byte[] ba = new byte[Integer.MAX_VALUE - 2];
|
||||
ba[0] = (byte) 0x80;
|
||||
try {
|
||||
BigInteger actual = new BigInteger(ba);
|
||||
throw new RuntimeException("new BigInteger(ba).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testBug8021204() {
|
||||
System.out.println("Testing Bug 8021204");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('1');
|
||||
for (int i = 0; i < (1 << 30) - 1; i++) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append('1');
|
||||
String s = sb.toString();
|
||||
sb = null;
|
||||
try {
|
||||
BigInteger actual = new BigInteger(s, 16);
|
||||
throw new RuntimeException("new BigInteger(\"1000...001\").bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testOverflowInBitSieve() {
|
||||
System.out.println("Testing overflow in BitSieve.sieveSingle");
|
||||
int bitLength = (5 << 27) - 1;
|
||||
try {
|
||||
BigInteger actual = new BigInteger(bitLength, 0, RANDOM);
|
||||
throw new RuntimeException("new BigInteger(bitLength, 0, null).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
BigInteger bi = BigInteger.ONE.shiftLeft(bitLength - 1).subtract(BigInteger.ONE);
|
||||
BigInteger actual = bi.nextProbablePrime();
|
||||
throw new RuntimeException("bi.nextActualPrime().bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testAdd() {
|
||||
System.out.println("Testing BigInteger.add");
|
||||
try {
|
||||
BigInteger actual = MAX_VALUE.add(BigInteger.ONE);
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.add(BigInteger.ONE).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testSubtract() {
|
||||
System.out.println("Testing BigInteger.subtract");
|
||||
try {
|
||||
BigInteger actual = MIN_VALUE.subtract(BigInteger.ONE);
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.subtract(BigInteger.ONE).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testMultiply() {
|
||||
System.out.println("Testing BigInteger.multiply");
|
||||
int py = 2000;
|
||||
int px = Integer.MAX_VALUE - py;
|
||||
BigInteger x = BigInteger.ONE.shiftLeft(px);
|
||||
BigInteger y = BigInteger.ONE.shiftLeft(py);
|
||||
try {
|
||||
BigInteger actual = x.multiply(y);
|
||||
throw new RuntimeException("(1 << " + px + " ) * (1 << " + py + ").bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testDivide() {
|
||||
System.out.println("Testing BigInteger.divide");
|
||||
check("BigInteger.MIN_VALUE.divide(BigInteger.valueOf(-1))",
|
||||
MIN_VALUE.divide(BigInteger.valueOf(-1)), MAX_VALUE);
|
||||
check("BigInteger.MIN_VALUE.divide(BigInteger.ONE)",
|
||||
MIN_VALUE.divide(BigInteger.ONE), MIN_VALUE);
|
||||
}
|
||||
|
||||
private static void testDivideAndRemainder(String msg, BigInteger dividend, BigInteger divisor,
|
||||
BigInteger expectedQuotent, BigInteger expectedRemainder) {
|
||||
BigInteger[] qr = dividend.divideAndRemainder(divisor);
|
||||
check(msg + "[0]", qr[0], expectedQuotent);
|
||||
check(msg + "[1]", qr[1], expectedRemainder);
|
||||
}
|
||||
|
||||
private static void testDivideAndRemainder() {
|
||||
System.out.println("Testing BigInteger.divideAndRemainder");
|
||||
testDivideAndRemainder("BigInteger.MIN_VALUE.divideAndRemainder(BigInteger.valueOf(-1))",
|
||||
MIN_VALUE, BigInteger.valueOf(-1),
|
||||
MAX_VALUE,
|
||||
BigInteger.ZERO);
|
||||
}
|
||||
|
||||
private static void testBug9005933() {
|
||||
System.out.println("Testing Bug 9005933");
|
||||
int dividendPow = 2147483646;
|
||||
int divisorPow = 1568;
|
||||
BigInteger dividend = BigInteger.ONE.shiftLeft(dividendPow);
|
||||
BigInteger divisor = BigInteger.ONE.shiftLeft(divisorPow);
|
||||
testDivideAndRemainder("(1 << " + dividendPow + ").divideAndRemainder(1 << " + divisorPow + ")",
|
||||
dividend, divisor,
|
||||
BigInteger.ONE.shiftLeft(dividendPow - divisorPow),
|
||||
BigInteger.ZERO);
|
||||
}
|
||||
|
||||
private static void testRemainder() {
|
||||
System.out.println("Testing BigInteger.remainder");
|
||||
check("BigInteger.MIN_VALUE.remainder(BigInteger.valueOf(-1))",
|
||||
MIN_VALUE.remainder(BigInteger.valueOf(-1)), BigInteger.ZERO);
|
||||
}
|
||||
|
||||
private static void testPow() {
|
||||
System.out.println("Testing BigInteger.pow");
|
||||
check("BigInteger.MIN_VALUE.pow(1)",
|
||||
MIN_VALUE.pow(1), MIN_VALUE);
|
||||
try {
|
||||
BigInteger actual = BigInteger.valueOf(4).pow(Integer.MAX_VALUE);
|
||||
throw new RuntimeException("BigInteger.valueOf(4).pow(Integer.MAX_VALUE).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testGcd() {
|
||||
System.out.println("Testing BigInteger.gcd");
|
||||
check("BigInteger.MIN_VALUE.gcd(BigInteger.MIN_VALUE)",
|
||||
MIN_VALUE.gcd(MIN_VALUE), MAX_VALUE);
|
||||
check("BigInteger.MIN_VALUE.gcd(BigInteger.ZERO)",
|
||||
MIN_VALUE.gcd(BigInteger.ZERO), MAX_VALUE);
|
||||
check("BigInteger.ZERO.gcd(MIN_VALUE)",
|
||||
BigInteger.ZERO.gcd(MIN_VALUE), MAX_VALUE);
|
||||
}
|
||||
|
||||
private static void testAbs() {
|
||||
System.out.println("Testing BigInteger.abs");
|
||||
check("BigInteger.MIN_VALUE.abs()",
|
||||
MIN_VALUE.abs(), MAX_VALUE);
|
||||
check("BigInteger.MAX_VALUE.abs()",
|
||||
MAX_VALUE.abs(), MAX_VALUE);
|
||||
}
|
||||
|
||||
private static void testNegate() {
|
||||
System.out.println("Testing BigInteger.negate");
|
||||
check("BigInteger.MIN_VALUE.negate()",
|
||||
MIN_VALUE.negate(), MAX_VALUE);
|
||||
check("BigInteger.MAX_VALUE.negate()",
|
||||
MAX_VALUE.negate(), MIN_VALUE);
|
||||
}
|
||||
|
||||
private static void testMod() {
|
||||
System.out.println("Testing BigInteger.mod");
|
||||
check("BigInteger.MIN_VALUE.mod(BigInteger.MAX_VALUE)",
|
||||
MIN_VALUE.mod(MAX_VALUE), BigInteger.ZERO);
|
||||
check("BigInteger.MAX_VALUE.mod(BigInteger.MAX_VALUE)",
|
||||
MIN_VALUE.mod(MAX_VALUE), BigInteger.ZERO);
|
||||
}
|
||||
|
||||
private static void testModPow() {
|
||||
System.out.println("Testing BigInteger.modPow");
|
||||
BigInteger x = BigInteger.valueOf(3);
|
||||
BigInteger m = BigInteger.valueOf(-4).subtract(MIN_VALUE);
|
||||
check("BigInteger.valueOf(3).modPow(BigInteger.ONE, m)",
|
||||
x.modPow(BigInteger.ONE, m), x);
|
||||
}
|
||||
|
||||
// slow test
|
||||
private static void testModInverse() {
|
||||
System.out.println("Testing BigInteger.modInverse");
|
||||
check("BigInteger.MIN_VALUE.modInverse(BigInteger.MAX_VALUE)",
|
||||
MIN_VALUE.modInverse(MAX_VALUE), MAX_VALUE.subtract(BigInteger.ONE));
|
||||
}
|
||||
|
||||
private static void testShiftLeft() {
|
||||
System.out.println("Testing BigInteger.shiftLeft");
|
||||
try {
|
||||
BigInteger actual = MIN_VALUE.shiftLeft(1);
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.shiftLeft(1).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
BigInteger actual = MAX_VALUE.shiftLeft(1);
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.shiftLeft(1).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testShiftRight() {
|
||||
System.out.println("Testing BigInteger.shiftRight");
|
||||
try {
|
||||
BigInteger actual = MIN_VALUE.shiftRight(-1);
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.shiftRight(-1).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
BigInteger actual = MAX_VALUE.shiftRight(-1);
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.shiftRight(-1).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testAnd() {
|
||||
System.out.println("Testing BigInteger.and");
|
||||
check("BigInteger.MIN_VALUE.and(BigInteger.MIN_VALUE)",
|
||||
MIN_VALUE.and(MIN_VALUE), MIN_VALUE);
|
||||
check("BigInteger.MAX_VALUE.and(BigInteger.MAX_VALUE)",
|
||||
MAX_VALUE.and(MAX_VALUE), MAX_VALUE);
|
||||
check("BigInteger.MIN_VALUE.and(BigInteger.MAX_VALUE)",
|
||||
MIN_VALUE.and(MAX_VALUE), BigInteger.ONE);
|
||||
try {
|
||||
BigInteger actual = MIN_VALUE.and(BigInteger.valueOf(-2));
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.and(-2)).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testOr() {
|
||||
System.out.println("Testing BigInteger.or");
|
||||
check("BigInteger.MIN_VALUE.or(BigInteger.MIN_VALUE)",
|
||||
MIN_VALUE.or(MIN_VALUE), MIN_VALUE);
|
||||
check("BigInteger.MAX_VALUE.or(BigInteger.MAX_VALUE)",
|
||||
MAX_VALUE.or(MAX_VALUE), MAX_VALUE);
|
||||
check("BigInteger.MIN_VALUE.and(BigInteger.MAX_VALUE)",
|
||||
MIN_VALUE.or(MAX_VALUE), BigInteger.valueOf(-1));
|
||||
}
|
||||
|
||||
private static void testXor() {
|
||||
System.out.println("Testing BigInteger.xor");
|
||||
check("BigInteger.MIN_VALUE.xor(BigInteger.MIN_VALUE)",
|
||||
MIN_VALUE.xor(MIN_VALUE), BigInteger.ZERO);
|
||||
check("BigInteger.MAX_VALUE.xor(BigInteger.MAX_VALUE)",
|
||||
MAX_VALUE.xor(MAX_VALUE), BigInteger.ZERO);
|
||||
check("BigInteger.MIN_VALUE.xor(BigInteger.MAX_VALUE)",
|
||||
MIN_VALUE.xor(MAX_VALUE), BigInteger.valueOf(-2));
|
||||
try {
|
||||
BigInteger actual = MIN_VALUE.xor(BigInteger.ONE);
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.xor(BigInteger.ONE)).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testNot() {
|
||||
System.out.println("Testing BigInteger.not");
|
||||
check("BigInteger.MIN_VALUE.not()",
|
||||
MIN_VALUE.not(), MAX_VALUE.subtract(BigInteger.ONE));
|
||||
try {
|
||||
BigInteger actual = MAX_VALUE.not();
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.not()).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testSetBit() {
|
||||
System.out.println("Testing BigInteger.setBit");
|
||||
check("BigInteger.MIN_VALUE.setBit(" + Integer.MAX_VALUE + ")",
|
||||
MIN_VALUE.setBit(Integer.MAX_VALUE), MIN_VALUE);
|
||||
try {
|
||||
BigInteger actual = MAX_VALUE.setBit(Integer.MAX_VALUE);
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.setBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testClearBit() {
|
||||
System.out.println("Testing BigInteger.clearBit");
|
||||
check("BigInteger.MAX_VALUE.clearBit(" + Integer.MAX_VALUE + ")",
|
||||
MAX_VALUE.clearBit(Integer.MAX_VALUE), MAX_VALUE);
|
||||
try {
|
||||
BigInteger actual = MIN_VALUE.clearBit(Integer.MAX_VALUE);
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.clearBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
BigInteger actual = MIN_VALUE.clearBit(0);
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.clearBit(0).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testFlipBit() {
|
||||
System.out.println("Testing BigInteger.flipBit");
|
||||
try {
|
||||
BigInteger actual = MIN_VALUE.flipBit(Integer.MAX_VALUE);
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.flipBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
BigInteger actual = MIN_VALUE.flipBit(0);
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.flipBit(0).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
BigInteger actual = MAX_VALUE.flipBit(Integer.MAX_VALUE);
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.flipBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testGetLowestSetBit() {
|
||||
System.out.println("Testing BigInteger.getLowestSetBit");
|
||||
check("BigInteger.MIN_VALUE.getLowestSetBit()",
|
||||
MIN_VALUE.getLowestSetBit(), 0);
|
||||
check("BigInteger.MAX_VALUE.getLowestSetBit()",
|
||||
MAX_VALUE.getLowestSetBit(), 0);
|
||||
}
|
||||
|
||||
private static void testBitLength() {
|
||||
System.out.println("Testing BigInteger.bitLength");
|
||||
check("BigInteger.MIN_NEXT.bitLength()",
|
||||
MIN_VALUE.bitLength(), Integer.MAX_VALUE);
|
||||
check("BigInteger.MAX_VALUE.bitLength()",
|
||||
MAX_VALUE.bitLength(), Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
private static void testBitCount() {
|
||||
System.out.println("Testing BigInteger.bitCount");
|
||||
check("BigInteger.MIN_VALUE.bitCount()",
|
||||
MIN_VALUE.bitCount(), Integer.MAX_VALUE - 1);
|
||||
check("BigInteger.MAX_VALUE.bitCount()",
|
||||
MAX_VALUE.bitCount(), Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
private static void testToString(String msg, int radix, BigInteger bi, int length, String startsWith, char c) {
|
||||
String s = bi.toString(radix);
|
||||
if (s.length() != length) {
|
||||
throw new RuntimeException(msg + ".length=" + s.length());
|
||||
}
|
||||
if (!s.startsWith(startsWith)) {
|
||||
throw new RuntimeException(msg + "[0]=" + s.substring(0, startsWith.length()));
|
||||
}
|
||||
for (int i = startsWith.length(); i < s.length(); i++) {
|
||||
if (s.charAt(i) != c) {
|
||||
throw new RuntimeException(msg + "[" + i + "]='" + s.charAt(i) + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testToString() {
|
||||
System.out.println("Testing BigInteger.toString");
|
||||
testToString("BigInteger.MIN_VALUE.toString(16)=", 16,
|
||||
BigInteger.valueOf(-1).shiftLeft(Integer.MAX_VALUE - 1),
|
||||
(1 << 29) + 1, "-4", '0');
|
||||
}
|
||||
|
||||
private static void testToByteArrayWithConstructor(String msg, BigInteger bi, int length, byte msb, byte b, byte lsb) {
|
||||
byte[] ba = bi.toByteArray();
|
||||
if (ba.length != length) {
|
||||
throw new RuntimeException(msg + ".length=" + ba.length);
|
||||
}
|
||||
if (ba[0] != msb) {
|
||||
throw new RuntimeException(msg + "[0]=" + ba[0]);
|
||||
}
|
||||
for (int i = 1; i < ba.length - 1; i++) {
|
||||
if (ba[i] != b) {
|
||||
throw new RuntimeException(msg + "[" + i + "]=" + ba[i]);
|
||||
}
|
||||
}
|
||||
if (ba[ba.length - 1] != lsb) {
|
||||
throw new RuntimeException(msg + "[" + (ba.length - 1) + "]=" + ba[ba.length - 1]);
|
||||
}
|
||||
BigInteger actual = new BigInteger(ba);
|
||||
if (!actual.equals(bi)) {
|
||||
throw new RuntimeException(msg + ".bitLength()=" + actual.bitLength());
|
||||
}
|
||||
}
|
||||
|
||||
private static void testToByteArrayWithConstructor() {
|
||||
System.out.println("Testing BigInteger.toByteArray with constructor");
|
||||
testToByteArrayWithConstructor("BigInteger.MIN_VALUE.toByteArray()",
|
||||
MIN_VALUE, (1 << 28), (byte) 0x80, (byte) 0x00, (byte) 0x01);
|
||||
testToByteArrayWithConstructor("BigInteger.MAX_VALUE.toByteArray()",
|
||||
MAX_VALUE, (1 << 28), (byte) 0x7f, (byte) 0xff, (byte) 0xff);
|
||||
|
||||
byte[] ba = new byte[1 << 28];
|
||||
ba[0] = (byte) 0x80;
|
||||
try {
|
||||
BigInteger actual = new BigInteger(-1, ba);
|
||||
throw new RuntimeException("new BigInteger(-1, ba).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
BigInteger actual = new BigInteger(1, ba);
|
||||
throw new RuntimeException("new BigInteger(1, ba).bitLength()=" + actual.bitLength());
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testIntValue() {
|
||||
System.out.println("Testing BigInteger.intValue");
|
||||
check("BigInteger.MIN_VALUE.intValue()",
|
||||
MIN_VALUE.intValue(), 1);
|
||||
check("BigInteger.MAX_VALUE.floatValue()",
|
||||
MAX_VALUE.intValue(), -1);
|
||||
}
|
||||
|
||||
private static void testLongValue() {
|
||||
System.out.println("Testing BigInteger.longValue");
|
||||
check("BigInteger.MIN_VALUE.longValue()",
|
||||
MIN_VALUE.longValue(), 1L);
|
||||
check("BigInteger.MAX_VALUE.longValue()",
|
||||
MAX_VALUE.longValue(), -1L);
|
||||
}
|
||||
|
||||
private static void testFloatValue() {
|
||||
System.out.println("Testing BigInteger.floatValue, Bug 8021203");
|
||||
check("BigInteger.MIN_VALUE_.floatValue()",
|
||||
MIN_VALUE.floatValue(), Float.NEGATIVE_INFINITY);
|
||||
check("BigInteger.MAX_VALUE.floatValue()",
|
||||
MAX_VALUE.floatValue(), Float.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
private static void testDoubleValue() {
|
||||
System.out.println("Testing BigInteger.doubleValue, Bug 8021203");
|
||||
check("BigInteger.MIN_VALUE.doubleValue()",
|
||||
MIN_VALUE.doubleValue(), Double.NEGATIVE_INFINITY);
|
||||
check("BigInteger.MAX_VALUE.doubleValue()",
|
||||
MAX_VALUE.doubleValue(), Double.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
private static void testSerialization(String msg, BigInteger bi) {
|
||||
try {
|
||||
ByteArrayOutputStream baOut = new ByteArrayOutputStream((1 << 28) + 1000);
|
||||
ObjectOutputStream out = new ObjectOutputStream(baOut);
|
||||
out.writeObject(bi);
|
||||
out.close();
|
||||
out = null;
|
||||
byte[] ba = baOut.toByteArray();
|
||||
baOut = null;
|
||||
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(ba));
|
||||
BigInteger actual = (BigInteger) in.readObject();
|
||||
if (!actual.equals(bi)) {
|
||||
throw new RuntimeException(msg + ".bitLength()=" + actual.bitLength());
|
||||
}
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(msg + " raised exception ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testSerialization() {
|
||||
System.out.println("Testing BigInteger serialization");
|
||||
testSerialization("BigInteger.MIN_VALUE.intValue()",
|
||||
MIN_VALUE);
|
||||
testSerialization("BigInteger.MAX_VALUE.floatValue()",
|
||||
MAX_VALUE);
|
||||
}
|
||||
|
||||
private static void testLongValueExact() {
|
||||
System.out.println("Testing BigInteger.longValueExact");
|
||||
try {
|
||||
long actual = MIN_VALUE.longValueExact();
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.longValueExact()= " + actual);
|
||||
} catch (ArithmeticException e) {
|
||||
// excpected
|
||||
}
|
||||
try {
|
||||
long actual = MAX_VALUE.longValueExact();
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.longValueExact()= " + actual);
|
||||
} catch (ArithmeticException e) {
|
||||
// excpected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testIntValueExact() {
|
||||
System.out.println("Testing BigInteger.intValueExact");
|
||||
try {
|
||||
long actual = MIN_VALUE.intValueExact();
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.intValueExact()= " + actual);
|
||||
} catch (ArithmeticException e) {
|
||||
// excpected
|
||||
}
|
||||
try {
|
||||
long actual = MAX_VALUE.intValueExact();
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.intValueExact()= " + actual);
|
||||
} catch (ArithmeticException e) {
|
||||
// excpected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testShortValueExact() {
|
||||
System.out.println("Testing BigInteger.shortValueExact");
|
||||
try {
|
||||
long actual = MIN_VALUE.shortValueExact();
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.shortValueExact()= " + actual);
|
||||
} catch (ArithmeticException e) {
|
||||
// excpected
|
||||
}
|
||||
try {
|
||||
long actual = MAX_VALUE.shortValueExact();
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.shortValueExact()= " + actual);
|
||||
} catch (ArithmeticException e) {
|
||||
// excpected
|
||||
}
|
||||
}
|
||||
|
||||
private static void testByteValueExact() {
|
||||
System.out.println("Testing BigInteger.byteValueExact");
|
||||
try {
|
||||
long actual = MIN_VALUE.byteValueExact();
|
||||
throw new RuntimeException("BigInteger.MIN_VALUE.byteValueExact()= " + actual);
|
||||
} catch (ArithmeticException e) {
|
||||
// excpected
|
||||
}
|
||||
try {
|
||||
long actual = MAX_VALUE.byteValueExact();
|
||||
throw new RuntimeException("BigInteger.MAX_VALUE.byteValueExact()= " + actual);
|
||||
} catch (ArithmeticException e) {
|
||||
// excpected
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String... args) {
|
||||
// subset zero indicates to run all subsets
|
||||
int subset = Integer.valueOf(System.getProperty("subset",
|
||||
String.valueOf(1 + RANDOM.nextInt(4))));
|
||||
if (subset < 0 || subset > 4) {
|
||||
throw new RuntimeException("Unknown subset " + subset);
|
||||
}
|
||||
if (subset == 0)
|
||||
System.out.println("Testing all subsets");
|
||||
else
|
||||
System.out.println("Testing subset " + subset);
|
||||
|
||||
if (subset == 0 || subset == 1) {
|
||||
testOverflowInMakePositive();
|
||||
testBug8021204();
|
||||
testOverflowInBitSieve();
|
||||
testAdd();
|
||||
testSubtract();
|
||||
}
|
||||
if (subset == 0 || subset == 2) {
|
||||
testMultiply();
|
||||
testDivide();
|
||||
testDivideAndRemainder();
|
||||
testBug9005933();
|
||||
}
|
||||
if (subset == 0 || subset == 3) {
|
||||
testRemainder();
|
||||
testPow();
|
||||
testGcd();
|
||||
testAbs();
|
||||
testNegate();
|
||||
testMod();
|
||||
testModPow();
|
||||
// testModInverse();
|
||||
testShiftLeft();
|
||||
testShiftRight();
|
||||
testAnd();
|
||||
testOr();
|
||||
testXor();
|
||||
testNot();
|
||||
testSetBit();
|
||||
testClearBit();
|
||||
testFlipBit();
|
||||
testGetLowestSetBit();
|
||||
testBitLength();
|
||||
testBitCount();
|
||||
}
|
||||
if (subset == 0 || subset == 4) {
|
||||
testToString();
|
||||
testToByteArrayWithConstructor();
|
||||
testIntValue();
|
||||
testLongValue();
|
||||
testFloatValue();
|
||||
testDoubleValue();
|
||||
testSerialization();
|
||||
testLongValueExact();
|
||||
testIntValueExact();
|
||||
testShortValueExact();
|
||||
testByteValueExact();
|
||||
}
|
||||
}
|
||||
}
|
||||
82
test/jdk/java/math/RoundingMode/RoundingModeTests.java
Normal file
82
test/jdk/java/math/RoundingMode/RoundingModeTests.java
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4851776 4891522 4905335
|
||||
* @summary Basic tests for the RoundingMode class.
|
||||
*/
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class RoundingModeTests {
|
||||
public static void main(String [] argv) {
|
||||
|
||||
// For each member of the family, make sure
|
||||
// rm == valueOf(rm.toString())
|
||||
|
||||
for(RoundingMode rm: RoundingMode.values()) {
|
||||
if (rm != RoundingMode.valueOf(rm.toString())) {
|
||||
throw new RuntimeException("Bad roundtrip conversion of " +
|
||||
rm.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Test that mapping of old integers to new values is correct
|
||||
if (RoundingMode.valueOf(BigDecimal.ROUND_CEILING) !=
|
||||
RoundingMode.CEILING) {
|
||||
throw new RuntimeException("Bad mapping for ROUND_CEILING");
|
||||
}
|
||||
|
||||
if (RoundingMode.valueOf(BigDecimal.ROUND_DOWN) !=
|
||||
RoundingMode.DOWN) {
|
||||
throw new RuntimeException("Bad mapping for ROUND_DOWN");
|
||||
}
|
||||
|
||||
if (RoundingMode.valueOf(BigDecimal.ROUND_FLOOR) !=
|
||||
RoundingMode.FLOOR) {
|
||||
throw new RuntimeException("Bad mapping for ROUND_FLOOR");
|
||||
}
|
||||
|
||||
if (RoundingMode.valueOf(BigDecimal.ROUND_HALF_DOWN) !=
|
||||
RoundingMode.HALF_DOWN) {
|
||||
throw new RuntimeException("Bad mapping for ROUND_HALF_DOWN");
|
||||
}
|
||||
|
||||
if (RoundingMode.valueOf(BigDecimal.ROUND_HALF_EVEN) !=
|
||||
RoundingMode.HALF_EVEN) {
|
||||
throw new RuntimeException("Bad mapping for ROUND_HALF_EVEN");
|
||||
}
|
||||
|
||||
if (RoundingMode.valueOf(BigDecimal.ROUND_HALF_UP) !=
|
||||
RoundingMode.HALF_UP) {
|
||||
throw new RuntimeException("Bad mapping for ROUND_HALF_UP");
|
||||
}
|
||||
|
||||
if (RoundingMode.valueOf(BigDecimal.ROUND_UNNECESSARY) !=
|
||||
RoundingMode.UNNECESSARY) {
|
||||
throw new RuntimeException("Bad mapping for ROUND_UNNECESARY");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue