Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/math/BigInteger/BigIntegerTest.java
38811 views
/*1* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225 483794626* @summary tests methods in BigInteger27* @run main/timeout=400 BigIntegerTest28* @author madbot29* @key randomness30*/3132import java.io.File;33import java.io.FileInputStream;34import java.io.FileOutputStream;35import java.io.ObjectInputStream;36import java.io.ObjectOutputStream;37import java.math.BigInteger;38import java.util.Random;3940/**41* This is a simple test class created to ensure that the results42* generated by BigInteger adhere to certain identities. Passing43* this test is a strong assurance that the BigInteger operations44* are working correctly.45*46* Four arguments may be specified which give the number of47* decimal digits you desire in the four batches of test numbers.48*49* The tests are performed on arrays of random numbers which are50* generated by a Random class as well as special cases which51* throw in boundary numbers such as 0, 1, maximum sized, etc.52*53*/54public class BigIntegerTest {55//56// Bit large number thresholds based on the int thresholds57// defined in BigInteger itself:58//59// KARATSUBA_THRESHOLD = 80 ints = 2560 bits60// TOOM_COOK_THRESHOLD = 240 ints = 7680 bits61// KARATSUBA_SQUARE_THRESHOLD = 128 ints = 4096 bits62// TOOM_COOK_SQUARE_THRESHOLD = 216 ints = 6912 bits63//64// SCHOENHAGE_BASE_CONVERSION_THRESHOLD = 20 ints = 640 bits65//66// BURNIKEL_ZIEGLER_THRESHOLD = 80 ints = 2560 bits67//68static final int BITS_KARATSUBA = 2560;69static final int BITS_TOOM_COOK = 7680;70static final int BITS_KARATSUBA_SQUARE = 4096;71static final int BITS_TOOM_COOK_SQUARE = 6912;72static final int BITS_SCHOENHAGE_BASE = 640;73static final int BITS_BURNIKEL_ZIEGLER = 2560;74static final int BITS_BURNIKEL_ZIEGLER_OFFSET = 1280;7576static final int ORDER_SMALL = 60;77static final int ORDER_MEDIUM = 100;78// #bits for testing Karatsuba79static final int ORDER_KARATSUBA = 2760;80// #bits for testing Toom-Cook and Burnikel-Ziegler81static final int ORDER_TOOM_COOK = 8000;82// #bits for testing Karatsuba squaring83static final int ORDER_KARATSUBA_SQUARE = 4200;84// #bits for testing Toom-Cook squaring85static final int ORDER_TOOM_COOK_SQUARE = 7000;8687static final int SIZE = 1000; // numbers per batch8889static Random rnd = new Random();90static boolean failure = false;9192public static void pow(int order) {93int failCount1 = 0;9495for (int i=0; i<SIZE; i++) {96// Test identity x^power == x*x*x ... *x97int power = rnd.nextInt(6) + 2;98BigInteger x = fetchNumber(order);99BigInteger y = x.pow(power);100BigInteger z = x;101102for (int j=1; j<power; j++)103z = z.multiply(x);104105if (!y.equals(z))106failCount1++;107}108report("pow for " + order + " bits", failCount1);109}110111public static void square(int order) {112int failCount1 = 0;113114for (int i=0; i<SIZE; i++) {115// Test identity x^2 == x*x116BigInteger x = fetchNumber(order);117BigInteger xx = x.multiply(x);118BigInteger x2 = x.pow(2);119120if (!x2.equals(xx))121failCount1++;122}123report("square for " + order + " bits", failCount1);124}125126public static void arithmetic(int order) {127int failCount = 0;128129for (int i=0; i<SIZE; i++) {130BigInteger x = fetchNumber(order);131while(x.compareTo(BigInteger.ZERO) != 1)132x = fetchNumber(order);133BigInteger y = fetchNumber(order/2);134while(x.compareTo(y) == -1)135y = fetchNumber(order/2);136if (y.equals(BigInteger.ZERO))137y = y.add(BigInteger.ONE);138139// Test identity ((x/y))*y + x%y - x == 0140// using separate divide() and remainder()141BigInteger baz = x.divide(y);142baz = baz.multiply(y);143baz = baz.add(x.remainder(y));144baz = baz.subtract(x);145if (!baz.equals(BigInteger.ZERO))146failCount++;147}148report("Arithmetic I for " + order + " bits", failCount);149150failCount = 0;151for (int i=0; i<100; i++) {152BigInteger x = fetchNumber(order);153while(x.compareTo(BigInteger.ZERO) != 1)154x = fetchNumber(order);155BigInteger y = fetchNumber(order/2);156while(x.compareTo(y) == -1)157y = fetchNumber(order/2);158if (y.equals(BigInteger.ZERO))159y = y.add(BigInteger.ONE);160161// Test identity ((x/y))*y + x%y - x == 0162// using divideAndRemainder()163BigInteger baz[] = x.divideAndRemainder(y);164baz[0] = baz[0].multiply(y);165baz[0] = baz[0].add(baz[1]);166baz[0] = baz[0].subtract(x);167if (!baz[0].equals(BigInteger.ZERO))168failCount++;169}170report("Arithmetic II for " + order + " bits", failCount);171}172173/**174* Sanity test for Karatsuba and 3-way Toom-Cook multiplication.175* For each of the Karatsuba and 3-way Toom-Cook multiplication thresholds,176* construct two factors each with a mag array one element shorter than the177* threshold, and with the most significant bit set and the rest of the bits178* random. Each of these numbers will therefore be below the threshold but179* if shifted left be above the threshold. Call the numbers 'u' and 'v' and180* define random shifts 'a' and 'b' in the range [1,32]. Then we have the181* identity182* <pre>183* (u << a)*(v << b) = (u*v) << (a + b)184* </pre>185* For Karatsuba multiplication, the right hand expression will be evaluated186* using the standard naive algorithm, and the left hand expression using187* the Karatsuba algorithm. For 3-way Toom-Cook multiplication, the right188* hand expression will be evaluated using Karatsuba multiplication, and the189* left hand expression using 3-way Toom-Cook multiplication.190*/191public static void multiplyLarge() {192int failCount = 0;193194BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA - 32 - 1);195for (int i=0; i<SIZE; i++) {196BigInteger x = fetchNumber(BITS_KARATSUBA - 32 - 1);197BigInteger u = base.add(x);198int a = 1 + rnd.nextInt(31);199BigInteger w = u.shiftLeft(a);200201BigInteger y = fetchNumber(BITS_KARATSUBA - 32 - 1);202BigInteger v = base.add(y);203int b = 1 + rnd.nextInt(32);204BigInteger z = v.shiftLeft(b);205206BigInteger multiplyResult = u.multiply(v).shiftLeft(a + b);207BigInteger karatsubaMultiplyResult = w.multiply(z);208209if (!multiplyResult.equals(karatsubaMultiplyResult)) {210failCount++;211}212}213214report("multiplyLarge Karatsuba", failCount);215216failCount = 0;217base = base.shiftLeft(BITS_TOOM_COOK - BITS_KARATSUBA);218for (int i=0; i<SIZE; i++) {219BigInteger x = fetchNumber(BITS_TOOM_COOK - 32 - 1);220BigInteger u = base.add(x);221BigInteger u2 = u.shiftLeft(1);222BigInteger y = fetchNumber(BITS_TOOM_COOK - 32 - 1);223BigInteger v = base.add(y);224BigInteger v2 = v.shiftLeft(1);225226BigInteger multiplyResult = u.multiply(v).shiftLeft(2);227BigInteger toomCookMultiplyResult = u2.multiply(v2);228229if (!multiplyResult.equals(toomCookMultiplyResult)) {230failCount++;231}232}233234report("multiplyLarge Toom-Cook", failCount);235}236237/**238* Sanity test for Karatsuba and 3-way Toom-Cook squaring.239* This test is analogous to {@link AbstractMethodError#multiplyLarge}240* with both factors being equal. The squaring methods will not be tested241* unless the <code>bigInteger.multiply(bigInteger)</code> tests whether242* the parameter is the same instance on which the method is being invoked243* and calls <code>square()</code> accordingly.244*/245public static void squareLarge() {246int failCount = 0;247248BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA_SQUARE - 32 - 1);249for (int i=0; i<SIZE; i++) {250BigInteger x = fetchNumber(BITS_KARATSUBA_SQUARE - 32 - 1);251BigInteger u = base.add(x);252int a = 1 + rnd.nextInt(31);253BigInteger w = u.shiftLeft(a);254255BigInteger squareResult = u.multiply(u).shiftLeft(2*a);256BigInteger karatsubaSquareResult = w.multiply(w);257258if (!squareResult.equals(karatsubaSquareResult)) {259failCount++;260}261}262263report("squareLarge Karatsuba", failCount);264265failCount = 0;266base = base.shiftLeft(BITS_TOOM_COOK_SQUARE - BITS_KARATSUBA_SQUARE);267for (int i=0; i<SIZE; i++) {268BigInteger x = fetchNumber(BITS_TOOM_COOK_SQUARE - 32 - 1);269BigInteger u = base.add(x);270int a = 1 + rnd.nextInt(31);271BigInteger w = u.shiftLeft(a);272273BigInteger squareResult = u.multiply(u).shiftLeft(2*a);274BigInteger toomCookSquareResult = w.multiply(w);275276if (!squareResult.equals(toomCookSquareResult)) {277failCount++;278}279}280281report("squareLarge Toom-Cook", failCount);282}283284/**285* Sanity test for Burnikel-Ziegler division. The Burnikel-Ziegler division286* algorithm is used when each of the dividend and the divisor has at least287* a specified number of ints in its representation. This test is based on288* the observation that if {@code w = u*pow(2,a)} and {@code z = v*pow(2,b)}289* where {@code abs(u) > abs(v)} and {@code a > b && b > 0}, then if290* {@code w/z = q1*z + r1} and {@code u/v = q2*v + r2}, then291* {@code q1 = q2*pow(2,a-b)} and {@code r1 = r2*pow(2,b)}. The test292* ensures that {@code v} is just under the B-Z threshold, that {@code z} is293* over the threshold and {@code w} is much larger than {@code z}. This294* implies that {@code u/v} uses the standard division algorithm and295* {@code w/z} uses the B-Z algorithm. The results of the two algorithms296* are then compared using the observation described in the foregoing and297* if they are not equal a failure is logged.298*/299public static void divideLarge() {300int failCount = 0;301302BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 33);303for (int i=0; i<SIZE; i++) {304BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 34, rnd);305BigInteger v = base.add(addend);306307BigInteger u = v.multiply(BigInteger.valueOf(2 + rnd.nextInt(Short.MAX_VALUE - 1)));308309if(rnd.nextBoolean()) {310u = u.negate();311}312if(rnd.nextBoolean()) {313v = v.negate();314}315316int a = BITS_BURNIKEL_ZIEGLER_OFFSET + rnd.nextInt(16);317int b = 1 + rnd.nextInt(16);318BigInteger w = u.multiply(BigInteger.ONE.shiftLeft(a));319BigInteger z = v.multiply(BigInteger.ONE.shiftLeft(b));320321BigInteger[] divideResult = u.divideAndRemainder(v);322divideResult[0] = divideResult[0].multiply(BigInteger.ONE.shiftLeft(a - b));323divideResult[1] = divideResult[1].multiply(BigInteger.ONE.shiftLeft(b));324BigInteger[] bzResult = w.divideAndRemainder(z);325326if (divideResult[0].compareTo(bzResult[0]) != 0 ||327divideResult[1].compareTo(bzResult[1]) != 0) {328failCount++;329}330}331332report("divideLarge", failCount);333}334335public static void bitCount() {336int failCount = 0;337338for (int i=0; i<SIZE*10; i++) {339int x = rnd.nextInt();340BigInteger bigX = BigInteger.valueOf((long)x);341int bit = (x < 0 ? 0 : 1);342int tmp = x, bitCount = 0;343for (int j=0; j<32; j++) {344bitCount += ((tmp & 1) == bit ? 1 : 0);345tmp >>= 1;346}347348if (bigX.bitCount() != bitCount) {349//System.err.println(x+": "+bitCount+", "+bigX.bitCount());350failCount++;351}352}353report("Bit Count", failCount);354}355356public static void bitLength() {357int failCount = 0;358359for (int i=0; i<SIZE*10; i++) {360int x = rnd.nextInt();361BigInteger bigX = BigInteger.valueOf((long)x);362int signBit = (x < 0 ? 0x80000000 : 0);363int tmp = x, bitLength, j;364for (j=0; j<32 && (tmp & 0x80000000)==signBit; j++)365tmp <<= 1;366bitLength = 32 - j;367368if (bigX.bitLength() != bitLength) {369//System.err.println(x+": "+bitLength+", "+bigX.bitLength());370failCount++;371}372}373374report("BitLength", failCount);375}376377public static void bitOps(int order) {378int failCount1 = 0, failCount2 = 0, failCount3 = 0;379380for (int i=0; i<SIZE*5; i++) {381BigInteger x = fetchNumber(order);382BigInteger y;383384// Test setBit and clearBit (and testBit)385if (x.signum() < 0) {386y = BigInteger.valueOf(-1);387for (int j=0; j<x.bitLength(); j++)388if (!x.testBit(j))389y = y.clearBit(j);390} else {391y = BigInteger.ZERO;392for (int j=0; j<x.bitLength(); j++)393if (x.testBit(j))394y = y.setBit(j);395}396if (!x.equals(y))397failCount1++;398399// Test flipBit (and testBit)400y = BigInteger.valueOf(x.signum()<0 ? -1 : 0);401for (int j=0; j<x.bitLength(); j++)402if (x.signum()<0 ^ x.testBit(j))403y = y.flipBit(j);404if (!x.equals(y))405failCount2++;406}407report("clearBit/testBit for " + order + " bits", failCount1);408report("flipBit/testBit for " + order + " bits", failCount2);409410for (int i=0; i<SIZE*5; i++) {411BigInteger x = fetchNumber(order);412413// Test getLowestSetBit()414int k = x.getLowestSetBit();415if (x.signum() == 0) {416if (k != -1)417failCount3++;418} else {419BigInteger z = x.and(x.negate());420int j;421for (j=0; j<z.bitLength() && !z.testBit(j); j++)422;423if (k != j)424failCount3++;425}426}427report("getLowestSetBit for " + order + " bits", failCount3);428}429430public static void bitwise(int order) {431432// Test identity x^y == x|y &~ x&y433int failCount = 0;434for (int i=0; i<SIZE; i++) {435BigInteger x = fetchNumber(order);436BigInteger y = fetchNumber(order);437BigInteger z = x.xor(y);438BigInteger w = x.or(y).andNot(x.and(y));439if (!z.equals(w))440failCount++;441}442report("Logic (^ | & ~) for " + order + " bits", failCount);443444// Test identity x &~ y == ~(~x | y)445failCount = 0;446for (int i=0; i<SIZE; i++) {447BigInteger x = fetchNumber(order);448BigInteger y = fetchNumber(order);449BigInteger z = x.andNot(y);450BigInteger w = x.not().or(y).not();451if (!z.equals(w))452failCount++;453}454report("Logic (&~ | ~) for " + order + " bits", failCount);455}456457public static void shift(int order) {458int failCount1 = 0;459int failCount2 = 0;460int failCount3 = 0;461462for (int i=0; i<100; i++) {463BigInteger x = fetchNumber(order);464int n = Math.abs(rnd.nextInt()%200);465466if (!x.shiftLeft(n).equals467(x.multiply(BigInteger.valueOf(2L).pow(n))))468failCount1++;469470BigInteger y[] =x.divideAndRemainder(BigInteger.valueOf(2L).pow(n));471BigInteger z = (x.signum()<0 && y[1].signum()!=0472? y[0].subtract(BigInteger.ONE)473: y[0]);474475BigInteger b = x.shiftRight(n);476477if (!b.equals(z)) {478System.err.println("Input is "+x.toString(2));479System.err.println("shift is "+n);480481System.err.println("Divided "+z.toString(2));482System.err.println("Shifted is "+b.toString(2));483if (b.toString().equals(z.toString()))484System.err.println("Houston, we have a problem.");485failCount2++;486}487488if (!x.shiftLeft(n).shiftRight(n).equals(x))489failCount3++;490}491report("baz shiftLeft for " + order + " bits", failCount1);492report("baz shiftRight for " + order + " bits", failCount2);493report("baz shiftLeft/Right for " + order + " bits", failCount3);494}495496public static void divideAndRemainder(int order) {497int failCount1 = 0;498499for (int i=0; i<SIZE; i++) {500BigInteger x = fetchNumber(order).abs();501while(x.compareTo(BigInteger.valueOf(3L)) != 1)502x = fetchNumber(order).abs();503BigInteger z = x.divide(BigInteger.valueOf(2L));504BigInteger y[] = x.divideAndRemainder(x);505if (!y[0].equals(BigInteger.ONE)) {506failCount1++;507System.err.println("fail1 x :"+x);508System.err.println(" y :"+y);509}510else if (!y[1].equals(BigInteger.ZERO)) {511failCount1++;512System.err.println("fail2 x :"+x);513System.err.println(" y :"+y);514}515516y = x.divideAndRemainder(z);517if (!y[0].equals(BigInteger.valueOf(2))) {518failCount1++;519System.err.println("fail3 x :"+x);520System.err.println(" y :"+y);521}522}523report("divideAndRemainder for " + order + " bits", failCount1);524}525526public static void stringConv() {527int failCount = 0;528529// Generic string conversion.530for (int i=0; i<100; i++) {531byte xBytes[] = new byte[Math.abs(rnd.nextInt())%100+1];532rnd.nextBytes(xBytes);533BigInteger x = new BigInteger(xBytes);534535for (int radix=Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {536String result = x.toString(radix);537BigInteger test = new BigInteger(result, radix);538if (!test.equals(x)) {539failCount++;540System.err.println("BigInteger toString: "+x);541System.err.println("Test: "+test);542System.err.println(radix);543}544}545}546547// String conversion straddling the Schoenhage algorithm crossover548// threshold, and at twice and four times the threshold.549for (int k = 0; k <= 2; k++) {550int factor = 1 << k;551int upper = factor * BITS_SCHOENHAGE_BASE + 33;552int lower = upper - 35;553554for (int bits = upper; bits >= lower; bits--) {555for (int i = 0; i < 50; i++) {556BigInteger x = BigInteger.ONE.shiftLeft(bits - 1).or(new BigInteger(bits - 2, rnd));557558for (int radix = Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {559String result = x.toString(radix);560BigInteger test = new BigInteger(result, radix);561if (!test.equals(x)) {562failCount++;563System.err.println("BigInteger toString: " + x);564System.err.println("Test: " + test);565System.err.println(radix);566}567}568}569}570}571572report("String Conversion", failCount);573}574575public static void byteArrayConv(int order) {576int failCount = 0;577578for (int i=0; i<SIZE; i++) {579BigInteger x = fetchNumber(order);580while (x.equals(BigInteger.ZERO))581x = fetchNumber(order);582BigInteger y = new BigInteger(x.toByteArray());583if (!x.equals(y)) {584failCount++;585System.err.println("orig is "+x);586System.err.println("new is "+y);587}588}589report("Array Conversion for " + order + " bits", failCount);590}591592public static void modInv(int order) {593int failCount = 0, successCount = 0, nonInvCount = 0;594595for (int i=0; i<SIZE; i++) {596BigInteger x = fetchNumber(order);597while(x.equals(BigInteger.ZERO))598x = fetchNumber(order);599BigInteger m = fetchNumber(order).abs();600while(m.compareTo(BigInteger.ONE) != 1)601m = fetchNumber(order).abs();602603try {604BigInteger inv = x.modInverse(m);605BigInteger prod = inv.multiply(x).remainder(m);606607if (prod.signum() == -1)608prod = prod.add(m);609610if (prod.equals(BigInteger.ONE))611successCount++;612else613failCount++;614} catch(ArithmeticException e) {615nonInvCount++;616}617}618report("Modular Inverse for " + order + " bits", failCount);619}620621public static void modExp(int order1, int order2) {622int failCount = 0;623624for (int i=0; i<SIZE/10; i++) {625BigInteger m = fetchNumber(order1).abs();626while(m.compareTo(BigInteger.ONE) != 1)627m = fetchNumber(order1).abs();628BigInteger base = fetchNumber(order2);629BigInteger exp = fetchNumber(8).abs();630631BigInteger z = base.modPow(exp, m);632BigInteger w = base.pow(exp.intValue()).mod(m);633if (!z.equals(w)) {634System.err.println("z is "+z);635System.err.println("w is "+w);636System.err.println("mod is "+m);637System.err.println("base is "+base);638System.err.println("exp is "+exp);639failCount++;640}641}642report("Exponentiation I for " + order1 + " and " +643order2 + " bits", failCount);644}645646// This test is based on Fermat's theorem647// which is not ideal because base must not be multiple of modulus648// and modulus must be a prime or pseudoprime (Carmichael number)649public static void modExp2(int order) {650int failCount = 0;651652for (int i=0; i<10; i++) {653BigInteger m = new BigInteger(100, 5, rnd);654while(m.compareTo(BigInteger.ONE) != 1)655m = new BigInteger(100, 5, rnd);656BigInteger exp = m.subtract(BigInteger.ONE);657BigInteger base = fetchNumber(order).abs();658while(base.compareTo(m) != -1)659base = fetchNumber(order).abs();660while(base.equals(BigInteger.ZERO))661base = fetchNumber(order).abs();662663BigInteger one = base.modPow(exp, m);664if (!one.equals(BigInteger.ONE)) {665System.err.println("m is "+m);666System.err.println("base is "+base);667System.err.println("exp is "+exp);668failCount++;669}670}671report("Exponentiation II for " + order + " bits", failCount);672}673674private static final int[] mersenne_powers = {675521, 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213, 19937,67621701, 23209, 44497, 86243, 110503, 132049, 216091, 756839, 859433,6771257787, 1398269, 2976221, 3021377, 6972593, 13466917 };678679private static final long[] carmichaels = {680561,1105,1729,2465,2821,6601,8911,10585,15841,29341,41041,46657,52633,68162745,63973,75361,101101,115921,126217,162401,172081,188461,252601,682278545,294409,314821,334153,340561,399001,410041,449065,488881,512461,683225593397919L };684685// Note: testing the larger ones takes too long.686private static final int NUM_MERSENNES_TO_TEST = 7;687// Note: this constant used for computed Carmichaels, not the array above688private static final int NUM_CARMICHAELS_TO_TEST = 5;689690private static final String[] customer_primes = {691"120000000000000000000000000000000019",692"633825300114114700748351603131",693"1461501637330902918203684832716283019651637554291",694"779626057591079617852292862756047675913380626199",695"857591696176672809403750477631580323575362410491",696"910409242326391377348778281801166102059139832131",697"929857869954035706722619989283358182285540127919",698"961301750640481375785983980066592002055764391999",699"1267617700951005189537696547196156120148404630231",700"1326015641149969955786344600146607663033642528339" };701702private static final BigInteger ZERO = BigInteger.ZERO;703private static final BigInteger ONE = BigInteger.ONE;704private static final BigInteger TWO = new BigInteger("2");705private static final BigInteger SIX = new BigInteger("6");706private static final BigInteger TWELVE = new BigInteger("12");707private static final BigInteger EIGHTEEN = new BigInteger("18");708709public static void prime() {710BigInteger p1, p2, c1;711int failCount = 0;712713// Test consistency714for(int i=0; i<10; i++) {715p1 = BigInteger.probablePrime(100, rnd);716if (!p1.isProbablePrime(100)) {717System.err.println("Consistency "+p1.toString(16));718failCount++;719}720}721722// Test some known Mersenne primes (2^n)-1723// The array holds the exponents, not the numbers being tested724for (int i=0; i<NUM_MERSENNES_TO_TEST; i++) {725p1 = new BigInteger("2");726p1 = p1.pow(mersenne_powers[i]);727p1 = p1.subtract(BigInteger.ONE);728if (!p1.isProbablePrime(100)) {729System.err.println("Mersenne prime "+i+ " failed.");730failCount++;731}732}733734// Test some primes reported by customers as failing in the past735for (int i=0; i<customer_primes.length; i++) {736p1 = new BigInteger(customer_primes[i]);737if (!p1.isProbablePrime(100)) {738System.err.println("Customer prime "+i+ " failed.");739failCount++;740}741}742743// Test some known Carmichael numbers.744for (int i=0; i<carmichaels.length; i++) {745c1 = BigInteger.valueOf(carmichaels[i]);746if(c1.isProbablePrime(100)) {747System.err.println("Carmichael "+i+ " reported as prime.");748failCount++;749}750}751752// Test some computed Carmichael numbers.753// Numbers of the form (6k+1)(12k+1)(18k+1) are Carmichael numbers if754// each of the factors is prime755int found = 0;756BigInteger f1 = new BigInteger(40, 100, rnd);757while (found < NUM_CARMICHAELS_TO_TEST) {758BigInteger k = null;759BigInteger f2, f3;760f1 = f1.nextProbablePrime();761BigInteger[] result = f1.subtract(ONE).divideAndRemainder(SIX);762if (result[1].equals(ZERO)) {763k = result[0];764f2 = k.multiply(TWELVE).add(ONE);765if (f2.isProbablePrime(100)) {766f3 = k.multiply(EIGHTEEN).add(ONE);767if (f3.isProbablePrime(100)) {768c1 = f1.multiply(f2).multiply(f3);769if (c1.isProbablePrime(100)) {770System.err.println("Computed Carmichael "771+c1.toString(16));772failCount++;773}774found++;775}776}777}778f1 = f1.add(TWO);779}780781// Test some composites that are products of 2 primes782for (int i=0; i<50; i++) {783p1 = BigInteger.probablePrime(100, rnd);784p2 = BigInteger.probablePrime(100, rnd);785c1 = p1.multiply(p2);786if (c1.isProbablePrime(100)) {787System.err.println("Composite failed "+c1.toString(16));788failCount++;789}790}791792for (int i=0; i<4; i++) {793p1 = BigInteger.probablePrime(600, rnd);794p2 = BigInteger.probablePrime(600, rnd);795c1 = p1.multiply(p2);796if (c1.isProbablePrime(100)) {797System.err.println("Composite failed "+c1.toString(16));798failCount++;799}800}801802report("Prime", failCount);803}804805private static final long[] primesTo100 = {8062,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97807};808809private static final long[] aPrimeSequence = {8101999999003L, 1999999013L, 1999999049L, 1999999061L, 1999999081L,8111999999087L, 1999999093L, 1999999097L, 1999999117L, 1999999121L,8121999999151L, 1999999171L, 1999999207L, 1999999219L, 1999999271L,8131999999321L, 1999999373L, 1999999423L, 1999999439L, 1999999499L,8141999999553L, 1999999559L, 1999999571L, 1999999609L, 1999999613L,8151999999621L, 1999999643L, 1999999649L, 1999999657L, 1999999747L,8161999999763L, 1999999777L, 1999999811L, 1999999817L, 1999999829L,8171999999853L, 1999999861L, 1999999871L, 1999999873818};819820public static void nextProbablePrime() throws Exception {821int failCount = 0;822BigInteger p1, p2, p3;823p1 = p2 = p3 = ZERO;824825// First test nextProbablePrime on the low range starting at zero826for (int i=0; i<primesTo100.length; i++) {827p1 = p1.nextProbablePrime();828if (p1.longValue() != primesTo100[i]) {829System.err.println("low range primes failed");830System.err.println("p1 is "+p1);831System.err.println("expected "+primesTo100[i]);832failCount++;833}834}835836// Test nextProbablePrime on a relatively small, known prime sequence837p1 = BigInteger.valueOf(aPrimeSequence[0]);838for (int i=1; i<aPrimeSequence.length; i++) {839p1 = p1.nextProbablePrime();840if (p1.longValue() != aPrimeSequence[i]) {841System.err.println("prime sequence failed");842failCount++;843}844}845846// Next, pick some large primes, use nextProbablePrime to find the847// next one, and make sure there are no primes in between848for (int i=0; i<100; i+=10) {849p1 = BigInteger.probablePrime(50 + i, rnd);850p2 = p1.add(ONE);851p3 = p1.nextProbablePrime();852while(p2.compareTo(p3) < 0) {853if (p2.isProbablePrime(100)){854System.err.println("nextProbablePrime failed");855System.err.println("along range "+p1.toString(16));856System.err.println("to "+p3.toString(16));857failCount++;858break;859}860p2 = p2.add(ONE);861}862}863864report("nextProbablePrime", failCount);865}866867public static void serialize() throws Exception {868int failCount = 0;869870String bitPatterns[] = {871"ffffffff00000000ffffffff00000000ffffffff00000000",872"ffffffffffffffffffffffff000000000000000000000000",873"ffffffff0000000000000000000000000000000000000000",874"10000000ffffffffffffffffffffffffffffffffffffffff",875"100000000000000000000000000000000000000000000000",876"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",877"-ffffffff00000000ffffffff00000000ffffffff00000000",878"-ffffffffffffffffffffffff000000000000000000000000",879"-ffffffff0000000000000000000000000000000000000000",880"-10000000ffffffffffffffffffffffffffffffffffffffff",881"-100000000000000000000000000000000000000000000000",882"-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"883};884885for(int i = 0; i < bitPatterns.length; i++) {886BigInteger b1 = new BigInteger(bitPatterns[i], 16);887BigInteger b2 = null;888889File f = new File("serialtest");890891try (FileOutputStream fos = new FileOutputStream(f)) {892try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {893oos.writeObject(b1);894oos.flush();895}896897try (FileInputStream fis = new FileInputStream(f);898ObjectInputStream ois = new ObjectInputStream(fis))899{900b2 = (BigInteger)ois.readObject();901}902903if (!b1.equals(b2) ||904!b1.equals(b1.or(b2))) {905failCount++;906System.err.println("Serialized failed for hex " +907b1.toString(16));908}909}910f.delete();911}912913for(int i=0; i<10; i++) {914BigInteger b1 = fetchNumber(rnd.nextInt(100));915BigInteger b2 = null;916File f = new File("serialtest");917try (FileOutputStream fos = new FileOutputStream(f)) {918try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {919oos.writeObject(b1);920oos.flush();921}922923try (FileInputStream fis = new FileInputStream(f);924ObjectInputStream ois = new ObjectInputStream(fis))925{926b2 = (BigInteger)ois.readObject();927}928}929930if (!b1.equals(b2) ||931!b1.equals(b1.or(b2)))932failCount++;933f.delete();934}935936report("Serialize", failCount);937}938939/**940* Main to interpret arguments and run several tests.941*942* Up to three arguments may be given to specify the SIZE of BigIntegers943* used for call parameters 1, 2, and 3. The SIZE is interpreted as944* the maximum number of decimal digits that the parameters will have.945*946*/947public static void main(String[] args) throws Exception {948949// Some variables for sizing test numbers in bits950int order1 = ORDER_MEDIUM;951int order2 = ORDER_SMALL;952int order3 = ORDER_KARATSUBA;953int order4 = ORDER_TOOM_COOK;954955if (args.length >0)956order1 = (int)((Integer.parseInt(args[0]))* 3.333);957if (args.length >1)958order2 = (int)((Integer.parseInt(args[1]))* 3.333);959if (args.length >2)960order3 = (int)((Integer.parseInt(args[2]))* 3.333);961if (args.length >3)962order4 = (int)((Integer.parseInt(args[3]))* 3.333);963964prime();965nextProbablePrime();966967arithmetic(order1); // small numbers968arithmetic(order3); // Karatsuba range969arithmetic(order4); // Toom-Cook / Burnikel-Ziegler range970971divideAndRemainder(order1); // small numbers972divideAndRemainder(order3); // Karatsuba range973divideAndRemainder(order4); // Toom-Cook / Burnikel-Ziegler range974975pow(order1);976pow(order3);977pow(order4);978979square(ORDER_MEDIUM);980square(ORDER_KARATSUBA_SQUARE);981square(ORDER_TOOM_COOK_SQUARE);982983bitCount();984bitLength();985bitOps(order1);986bitwise(order1);987988shift(order1);989990byteArrayConv(order1);991992modInv(order1); // small numbers993modInv(order3); // Karatsuba range994modInv(order4); // Toom-Cook / Burnikel-Ziegler range995996modExp(order1, order2);997modExp2(order1);998999stringConv();1000serialize();10011002multiplyLarge();1003squareLarge();1004divideLarge();10051006if (failure)1007throw new RuntimeException("Failure in BigIntegerTest.");1008}10091010/*1011* Get a random or boundary-case number. This is designed to provide1012* a lot of numbers that will find failure points, such as max sized1013* numbers, empty BigIntegers, etc.1014*1015* If order is less than 2, order is changed to 2.1016*/1017private static BigInteger fetchNumber(int order) {1018boolean negative = rnd.nextBoolean();1019int numType = rnd.nextInt(7);1020BigInteger result = null;1021if (order < 2) order = 2;10221023switch (numType) {1024case 0: // Empty1025result = BigInteger.ZERO;1026break;10271028case 1: // One1029result = BigInteger.ONE;1030break;10311032case 2: // All bits set in number1033int numBytes = (order+7)/8;1034byte[] fullBits = new byte[numBytes];1035for(int i=0; i<numBytes; i++)1036fullBits[i] = (byte)0xff;1037int excessBits = 8*numBytes - order;1038fullBits[0] &= (1 << (8-excessBits)) - 1;1039result = new BigInteger(1, fullBits);1040break;10411042case 3: // One bit in number1043result = BigInteger.ONE.shiftLeft(rnd.nextInt(order));1044break;10451046case 4: // Random bit density1047byte[] val = new byte[(order+7)/8];1048int iterations = rnd.nextInt(order);1049for (int i=0; i<iterations; i++) {1050int bitIdx = rnd.nextInt(order);1051val[bitIdx/8] |= 1 << (bitIdx%8);1052}1053result = new BigInteger(1, val);1054break;1055case 5: // Runs of consecutive ones and zeros1056result = ZERO;1057int remaining = order;1058int bit = rnd.nextInt(2);1059while (remaining > 0) {1060int runLength = Math.min(remaining, rnd.nextInt(order));1061result = result.shiftLeft(runLength);1062if (bit > 0)1063result = result.add(ONE.shiftLeft(runLength).subtract(ONE));1064remaining -= runLength;1065bit = 1 - bit;1066}1067break;10681069default: // random bits1070result = new BigInteger(order, rnd);1071}10721073if (negative)1074result = result.negate();10751076return result;1077}10781079static void report(String testName, int failCount) {1080System.err.println(testName+": " +1081(failCount==0 ? "Passed":"Failed("+failCount+")"));1082if (failCount > 0)1083failure = true;1084}1085}108610871088