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:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -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());
}
}

File diff suppressed because it is too large Load diff

View 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);
});
}
}

View 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;
}
}

View 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.");
}
}
}

View 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");
}
}
}

View 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
}
}
}

View 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));
}
}

View 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);
}
}

View 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");
}
}

View 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.");
}
}
}
}

View 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");
}
}

View 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");
}
}
}

View 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;
}
}

View 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
}
}
}
}

View 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;
}
}
}

View 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.");
}
}
}

View 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]);
}
}
}

View 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));
}
}
}

View 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();
}
}
}

View 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;
}
}

View 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.");
}
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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");
}
}
}

View file

@ -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");
}
}
}

View file

@ -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();
}
}
}