BigIntegerTest.java revision 2362
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 4161971 4227146 4194389 4823171 4624738 4812225
* @summary tests methods in BigInteger
* @author madbot
*/
/**
* This is a simple test class created to ensure that the results
* generated by BigInteger adhere to certain identities. Passing
* this test is a strong assurance that the BigInteger operations
* are working correctly.
*
* Three arguments may be specified which give the number of
* decimal digits you desire in the three batches of test numbers.
*
* The tests are performed on arrays of random numbers which are
* generated by a Random class as well as special cases which
* throw in boundary numbers such as 0, 1, maximum sized, etc.
*
*/
public class BigIntegerTest {
static boolean failure = false;
// Some variables for sizing test numbers in bits
private static int order1 = 100;
private static int order2 = 60;
private static int order3 = 30;
public static void pow() {
int failCount1 = 0;
for (int i=0; i<size; i++) {
BigInteger z = x;
for (int j=1; j<power; j++)
z = z.multiply(x);
if (!y.equals(z))
failCount1++;
}
}
public static void arithmetic() {
int failCount = 0;
for (int i=0; i<size; i++) {
x = fetchNumber(order1);
while(x.compareTo(y) == -1)
failCount++;
}
failCount = 0;
for (int i=0; i<100; i++) {
x = fetchNumber(order1);
while(x.compareTo(y) == -1)
failCount++;
}
}
public static void bitCount() {
int failCount = 0;
for (int j=0; j<32; j++) {
tmp >>= 1;
}
//System.err.println(x+": "+bitCount+", "+bigX.bitCount());
failCount++;
}
}
}
public static void bitLength() {
int failCount = 0;
tmp <<= 1;
bitLength = 32 - j;
//System.err.println(x+": "+bitLength+", "+bigX.bitLength());
failCount++;
}
}
}
public static void bitOps() {
BigInteger y;
/* Test setBit and clearBit (and testBit) */
if (x.signum() < 0) {
for (int j=0; j<x.bitLength(); j++)
if (!x.testBit(j))
y = y.clearBit(j);
} else {
y = BigInteger.ZERO;
for (int j=0; j<x.bitLength(); j++)
if (x.testBit(j))
y = y.setBit(j);
}
if (!x.equals(y))
failCount1++;
/* Test flipBit (and testBit) */
for (int j=0; j<x.bitLength(); j++)
y = y.flipBit(j);
if (!x.equals(y))
failCount2++;
}
/* Test getLowestSetBit() */
int k = x.getLowestSetBit();
if (x.signum() == 0) {
if (k != -1)
failCount3++;
} else {
int j;
;
if (k != j)
failCount3++;
}
}
}
public static void bitwise() {
/* Test identity x^y == x|y &~ x&y */
int failCount = 0;
for (int i=0; i<size; i++) {
BigInteger z = x.xor(y);
if (!z.equals(w))
failCount++;
}
/* Test identity x &~ y == ~(~x | y) */
failCount = 0;
for (int i=0; i<size; i++) {
BigInteger z = x.andNot(y);
if (!z.equals(w))
failCount++;
}
}
public static void shift() {
int failCount1 = 0;
int failCount2 = 0;
int failCount3 = 0;
for (int i=0; i<100; i++) {
failCount1++;
: y[0]);
BigInteger b = x.shiftRight(n);
if (!b.equals(z)) {
failCount2++;
}
failCount3++;
}
}
public static void divideAndRemainder() {
int failCount1 = 0;
for (int i=0; i<size; i++) {
BigInteger y[] = x.divideAndRemainder(x);
failCount1++;
}
failCount1++;
}
y = x.divideAndRemainder(z);
failCount1++;
}
}
}
public static void stringConv() {
int failCount = 0;
for (int i=0; i<100; i++) {
failCount++;
}
}
}
}
public static void byteArrayConv() {
int failCount = 0;
for (int i=0; i<size; i++) {
x = fetchNumber(order1);
if (!x.equals(y)) {
failCount++;
}
}
}
public static void modInv() {
for (int i=0; i<size; i++) {
x = fetchNumber(order1);
try {
successCount++;
else
failCount++;
} catch(ArithmeticException e) {
nonInvCount++;
}
}
}
public static void modExp() {
int failCount = 0;
if (!z.equals(w)) {
failCount++;
}
}
}
// This test is based on Fermat's theorem
// which is not ideal because base must not be multiple of modulus
// and modulus must be a prime or pseudoprime (Carmichael number)
public static void modExp2() {
int failCount = 0;
for (int i=0; i<10; i++) {
failCount++;
}
}
}
private static final int[] mersenne_powers = {
521, 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213, 19937,
21701, 23209, 44497, 86243, 110503, 132049, 216091, 756839, 859433,
1257787, 1398269, 2976221, 3021377, 6972593, 13466917 };
private static final long[] carmichaels = {
561,1105,1729,2465,2821,6601,8911,10585,15841,29341,41041,46657,52633,
62745,63973,75361,101101,115921,126217,162401,172081,188461,252601,
278545,294409,314821,334153,340561,399001,410041,449065,488881,512461,
225593397919L };
// Note: testing the larger ones takes too long.
private static final int NUM_MERSENNES_TO_TEST = 7;
// Note: this constant used for computed Carmichaels, not the array above
private static final int NUM_CARMICHAELS_TO_TEST = 5;
private static final String[] customer_primes = {
"120000000000000000000000000000000019",
"633825300114114700748351603131",
"1461501637330902918203684832716283019651637554291",
"779626057591079617852292862756047675913380626199",
"857591696176672809403750477631580323575362410491",
"910409242326391377348778281801166102059139832131",
"929857869954035706722619989283358182285540127919",
"961301750640481375785983980066592002055764391999",
"1267617700951005189537696547196156120148404630231",
"1326015641149969955786344600146607663033642528339" };
public static void prime() {
int failCount = 0;
// Test consistency
for(int i=0; i<10; i++) {
failCount++;
}
}
// Test some known Mersenne primes (2^n)-1
// The array holds the exponents, not the numbers being tested
for (int i=0; i<NUM_MERSENNES_TO_TEST; i++) {
failCount++;
}
}
// Test some primes reported by customers as failing in the past
failCount++;
}
}
// Test some known Carmichael numbers.
failCount++;
}
}
// Test some computed Carmichael numbers.
// Numbers of the form (6k+1)(12k+1)(18k+1) are Carmichael numbers if
// each of the factors is prime
int found = 0;
while (found < NUM_CARMICHAELS_TO_TEST) {
BigInteger k = null;
k = result[0];
failCount++;
}
found++;
}
}
}
}
// Test some composites that are products of 2 primes
for (int i=0; i<50; i++) {
failCount++;
}
}
for (int i=0; i<4; i++) {
failCount++;
}
}
}
private static final long[] primesTo100 = {
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97
};
private static final long[] aPrimeSequence = {
1999999003L, 1999999013L, 1999999049L, 1999999061L, 1999999081L,
1999999087L, 1999999093L, 1999999097L, 1999999117L, 1999999121L,
1999999151L, 1999999171L, 1999999207L, 1999999219L, 1999999271L,
1999999321L, 1999999373L, 1999999423L, 1999999439L, 1999999499L,
1999999553L, 1999999559L, 1999999571L, 1999999609L, 1999999613L,
1999999621L, 1999999643L, 1999999649L, 1999999657L, 1999999747L,
1999999763L, 1999999777L, 1999999811L, 1999999817L, 1999999829L,
1999999853L, 1999999861L, 1999999871L, 1999999873
};
public static void nextProbablePrime() throws Exception {
int failCount = 0;
// First test nextProbablePrime on the low range starting at zero
failCount++;
}
}
// Test nextProbablePrime on a relatively small, known prime sequence
failCount++;
}
}
// Next, pick some large primes, use nextProbablePrime to find the
// next one, and make sure there are no primes in between
for (int i=0; i<100; i+=10) {
failCount++;
break;
}
}
}
}
int failCount = 0;
String bitPatterns[] = {
"ffffffff00000000ffffffff00000000ffffffff00000000",
"ffffffffffffffffffffffff000000000000000000000000",
"ffffffff0000000000000000000000000000000000000000",
"10000000ffffffffffffffffffffffffffffffffffffffff",
"100000000000000000000000000000000000000000000000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"-ffffffff00000000ffffffff00000000ffffffff00000000",
"-ffffffffffffffffffffffff000000000000000000000000",
"-ffffffff0000000000000000000000000000000000000000",
"-10000000ffffffffffffffffffffffffffffffffffffffff",
"-100000000000000000000000000000000000000000000000",
"-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
};
try {
try {
} finally {
}
try {
try {
} finally {
}
} finally {
}
failCount++;
}
} finally {
}
f.delete();
}
for(int i=0; i<10; i++) {
try {
try {
} finally {
}
try {
try {
} finally {
}
} finally {
}
} finally {
}
failCount++;
f.delete();
}
}
/**
* Main to interpret arguments and run several tests.
*
* Up to three arguments may be given to specify the size of BigIntegers
* used for call parameters 1, 2, and 3. The size is interpreted as
* the maximum number of decimal digits that the parameters will have.
*
*/
prime();
arithmetic();
pow();
bitCount();
bitLength();
bitOps();
bitwise();
shift();
modInv();
modExp();
modExp2();
stringConv();
serialize();
if (failure)
throw new RuntimeException("Failure in BigIntegerTest.");
}
/*
* 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 BigIntegers, etc.
*
* If order is less than 2, order is changed to 2.
*/
switch (numType) {
case 0: // Empty
break;
case 1: // One
break;
case 2: // All bits set in number
for(int i=0; i<numBytes; i++)
fullBits[i] = (byte)0xff;
break;
case 3: // One bit in number
break;
case 4: // Random bit density
for(int i=0; i<iterations; i++) {
}
break;
default: // random bits
}
if (negative)
return result;
}
if (failCount > 0)
failure = true;
}
}