test/java/math/BigInteger/BigIntegerTest.java

Print this page
rev 11823 : 8078672: Print and allow setting by Java property seeds used to initialize Random instances in java.lang numerics tests
Summary: Add ability to initial the random number generator from the system property "seed" and print to STDOUT the seed value actually used.
Reviewed-by: XXX

@@ -21,12 +21,14 @@
  * questions.
  */
 
 /*
  * @test
- * @library ..
- * @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225 4837946 4026465 8074460
+ * @library /lib/testlibrary/
+ * @build jdk.testlibrary.*
+ * @run main BigIntegerTest
+ * @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225 4837946 4026465 8074460 8078672
  * @summary tests methods in BigInteger (use -Dseed=X to set PRNG seed)
  * @run main/timeout=400 BigIntegerTest
  * @author madbot
  * @key randomness
  */

@@ -35,10 +37,11 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.math.BigInteger;
+import java.util.Random;
 
 /**
  * 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

@@ -85,11 +88,11 @@
     // #bits for testing Toom-Cook squaring
     static final int ORDER_TOOM_COOK_SQUARE = 7000;
 
     static final int SIZE = 1000; // numbers per batch
 
-    private static RandomSeed rndSeed = new RandomSeed(false);
+    private static Random random = RandomFactory.getRandom();
 
     static boolean failure = false;
 
     public static void constructor() {
         int failCount = 0;

@@ -97,11 +100,11 @@
         // --- guard condition tests for array indexing ---
 
         int arrayLength = 23;
         int halfLength = arrayLength/2;
         byte[] array = new byte[arrayLength];
-        rndSeed.getRandom().nextBytes(array);
+        random.nextBytes(array);
 
         int[][] offLen = new int[][] { // offset, length, num exceptions
             {-1, arrayLength, 1},                         // negative offset
             {0, arrayLength, 0},                          // OK
             {1, arrayLength, 1},                          // length overflow

@@ -161,11 +164,11 @@
                 failCount++;
             }
         }
 
         byte[] magNonZeroLength = new byte[42];
-        rndSeed.getRandom().nextBytes(magNonZeroLength);
+        random.nextBytes(magNonZeroLength);
         for (int signum = -1; signum <= 1; signum++) {
             BigInteger bi = new BigInteger(signum, magNonZeroLength, 0, 0);
             if (bi.compareTo(BigInteger.ZERO) != 0) {
                 System.err.println("C: Zero length BigInteger != 0 for signum " + signum);
                 failCount++;

@@ -174,28 +177,28 @@
 
         // --- tests for accurate creation of non-zero BigIntegers ---
 
         for (int i = 0; i < SIZE; i++) {
             // create reference value via a different code path from those tested
-            BigInteger reference = new BigInteger(2 + rndSeed.getRandom().nextInt(336), 4, rndSeed.getRandom());
+            BigInteger reference = new BigInteger(2 + random.nextInt(336), 4, random);
 
             byte[] refArray = reference.toByteArray();
             int refLen = refArray.length;
-            int factor = rndSeed.getRandom().nextInt(5);
-            int objLen = refArray.length + factor*rndSeed.getRandom().nextInt(refArray.length) + 1;
-            int offset = rndSeed.getRandom().nextInt(objLen - refLen);
+            int factor = random.nextInt(5);
+            int objLen = refArray.length + factor*random.nextInt(refArray.length) + 1;
+            int offset = random.nextInt(objLen - refLen);
             byte[] objArray = new byte[objLen];
             System.arraycopy(refArray, 0, objArray, offset, refLen);
 
             BigInteger twosComp = new BigInteger(objArray, offset, refLen);
             if (twosComp.compareTo(reference) != 0) {
                 System.err.println("Two's-complement BigInteger not equal for offset " +
                         offset + " and length " + refLen);
                 failCount++;
             }
 
-            boolean isNegative = rndSeed.getRandom().nextBoolean();
+            boolean isNegative = random.nextBoolean();
             BigInteger signMag = new BigInteger(isNegative ? -1 : 1, objArray, offset, refLen);
             if (signMag.compareTo(isNegative ? reference.negate() : reference) != 0) {
                 System.err.println("Sign-magnitude BigInteger not equal for offset " +
                         offset + " and length " + refLen);
                 failCount++;

@@ -208,11 +211,11 @@
     public static void pow(int order) {
         int failCount1 = 0;
 
         for (int i=0; i<SIZE; i++) {
             // Test identity x^power == x*x*x ... *x
-            int power = rndSeed.getRandom().nextInt(6) + 2;
+            int power = random.nextInt(6) + 2;
             BigInteger x = fetchNumber(order);
             BigInteger y = x.pow(power);
             BigInteger z = x;
 
             for (int j=1; j<power; j++)

@@ -309,16 +312,16 @@
 
         BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA - 32 - 1);
         for (int i=0; i<SIZE; i++) {
             BigInteger x = fetchNumber(BITS_KARATSUBA - 32 - 1);
             BigInteger u = base.add(x);
-            int a = 1 + rndSeed.getRandom().nextInt(31);
+            int a = 1 + random.nextInt(31);
             BigInteger w = u.shiftLeft(a);
 
             BigInteger y = fetchNumber(BITS_KARATSUBA - 32 - 1);
             BigInteger v = base.add(y);
-            int b = 1 + rndSeed.getRandom().nextInt(32);
+            int b = 1 + random.nextInt(32);
             BigInteger z = v.shiftLeft(b);
 
             BigInteger multiplyResult = u.multiply(v).shiftLeft(a + b);
             BigInteger karatsubaMultiplyResult = w.multiply(z);
 

@@ -363,11 +366,11 @@
 
         BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA_SQUARE - 32 - 1);
         for (int i=0; i<SIZE; i++) {
             BigInteger x = fetchNumber(BITS_KARATSUBA_SQUARE - 32 - 1);
             BigInteger u = base.add(x);
-            int a = 1 + rndSeed.getRandom().nextInt(31);
+            int a = 1 + random.nextInt(31);
             BigInteger w = u.shiftLeft(a);
 
             BigInteger squareResult = u.multiply(u).shiftLeft(2*a);
             BigInteger karatsubaSquareResult = w.multiply(w);
 

@@ -381,11 +384,11 @@
         failCount = 0;
         base = base.shiftLeft(BITS_TOOM_COOK_SQUARE - BITS_KARATSUBA_SQUARE);
         for (int i=0; i<SIZE; i++) {
             BigInteger x = fetchNumber(BITS_TOOM_COOK_SQUARE - 32 - 1);
             BigInteger u = base.add(x);
-            int a = 1 + rndSeed.getRandom().nextInt(31);
+            int a = 1 + random.nextInt(31);
             BigInteger w = u.shiftLeft(a);
 
             BigInteger squareResult = u.multiply(u).shiftLeft(2*a);
             BigInteger toomCookSquareResult = w.multiply(w);
 

@@ -415,24 +418,24 @@
     public static void divideLarge() {
         int failCount = 0;
 
         BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 33);
         for (int i=0; i<SIZE; i++) {
-            BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 34, rndSeed.getRandom());
+            BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 34, random);
             BigInteger v = base.add(addend);
 
-            BigInteger u = v.multiply(BigInteger.valueOf(2 + rndSeed.getRandom().nextInt(Short.MAX_VALUE - 1)));
+            BigInteger u = v.multiply(BigInteger.valueOf(2 + random.nextInt(Short.MAX_VALUE - 1)));
 
-            if(rndSeed.getRandom().nextBoolean()) {
+            if(random.nextBoolean()) {
                 u = u.negate();
             }
-            if(rndSeed.getRandom().nextBoolean()) {
+            if(random.nextBoolean()) {
                 v = v.negate();
             }
 
-            int a = BITS_BURNIKEL_ZIEGLER_OFFSET + rndSeed.getRandom().nextInt(16);
-            int b = 1 + rndSeed.getRandom().nextInt(16);
+            int a = BITS_BURNIKEL_ZIEGLER_OFFSET + random.nextInt(16);
+            int b = 1 + random.nextInt(16);
             BigInteger w = u.multiply(BigInteger.ONE.shiftLeft(a));
             BigInteger z = v.multiply(BigInteger.ONE.shiftLeft(b));
 
             BigInteger[] divideResult = u.divideAndRemainder(v);
             divideResult[0] = divideResult[0].multiply(BigInteger.ONE.shiftLeft(a - b));

@@ -450,11 +453,11 @@
 
     public static void bitCount() {
         int failCount = 0;
 
         for (int i=0; i<SIZE*10; i++) {
-            int x = rndSeed.getRandom().nextInt();
+            int x = random.nextInt();
             BigInteger bigX = BigInteger.valueOf((long)x);
             int bit = (x < 0 ? 0 : 1);
             int tmp = x, bitCount = 0;
             for (int j=0; j<32; j++) {
                 bitCount += ((tmp & 1) == bit ? 1 : 0);

@@ -471,11 +474,11 @@
 
     public static void bitLength() {
         int failCount = 0;
 
         for (int i=0; i<SIZE*10; i++) {
-            int x = rndSeed.getRandom().nextInt();
+            int x = random.nextInt();
             BigInteger bigX = BigInteger.valueOf((long)x);
             int signBit = (x < 0 ? 0x80000000 : 0);
             int tmp = x, bitLength, j;
             for (j=0; j<32 && (tmp & 0x80000000)==signBit; j++)
                 tmp <<= 1;

@@ -575,11 +578,11 @@
         int failCount2 = 0;
         int failCount3 = 0;
 
         for (int i=0; i<100; i++) {
             BigInteger x = fetchNumber(order);
-            int n = Math.abs(rndSeed.getRandom().nextInt()%200);
+            int n = Math.abs(random.nextInt()%200);
 
             if (!x.shiftLeft(n).equals
                 (x.multiply(BigInteger.valueOf(2L).pow(n))))
                 failCount1++;
 

@@ -642,12 +645,12 @@
     public static void stringConv() {
         int failCount = 0;
 
         // Generic string conversion.
         for (int i=0; i<100; i++) {
-            byte xBytes[] = new byte[Math.abs(rndSeed.getRandom().nextInt())%100+1];
-            rndSeed.getRandom().nextBytes(xBytes);
+            byte xBytes[] = new byte[Math.abs(random.nextInt())%100+1];
+            random.nextBytes(xBytes);
             BigInteger x = new BigInteger(xBytes);
 
             for (int radix=Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
                 String result = x.toString(radix);
                 BigInteger test = new BigInteger(result, radix);

@@ -667,11 +670,11 @@
             int upper = factor * BITS_SCHOENHAGE_BASE + 33;
             int lower = upper - 35;
 
             for (int bits = upper; bits >= lower; bits--) {
                 for (int i = 0; i < 50; i++) {
-                    BigInteger x = BigInteger.ONE.shiftLeft(bits - 1).or(new BigInteger(bits - 2, rndSeed.getRandom()));
+                    BigInteger x = BigInteger.ONE.shiftLeft(bits - 1).or(new BigInteger(bits - 2, random));
 
                     for (int radix = Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
                         String result = x.toString(radix);
                         BigInteger test = new BigInteger(result, radix);
                         if (!test.equals(x)) {

@@ -764,13 +767,13 @@
     // and modulus must be a prime or pseudoprime (Carmichael number)
     public static void modExp2(int order) {
         int failCount = 0;
 
         for (int i=0; i<10; i++) {
-            BigInteger m = new BigInteger(100, 5, rndSeed.getRandom());
+            BigInteger m = new BigInteger(100, 5, random);
             while(m.compareTo(BigInteger.ONE) != 1)
-                m = new BigInteger(100, 5, rndSeed.getRandom());
+                m = new BigInteger(100, 5, random);
             BigInteger exp = m.subtract(BigInteger.ONE);
             BigInteger base = fetchNumber(order).abs();
             while(base.compareTo(m) != -1)
                 base = fetchNumber(order).abs();
             while(base.equals(BigInteger.ZERO))

@@ -826,11 +829,11 @@
         BigInteger p1, p2, c1;
         int failCount = 0;
 
         // Test consistency
         for(int i=0; i<10; i++) {
-            p1 = BigInteger.probablePrime(100, rndSeed.getRandom());
+            p1 = BigInteger.probablePrime(100, random);
             if (!p1.isProbablePrime(100)) {
                 System.err.println("Consistency "+p1.toString(16));
                 failCount++;
             }
         }

@@ -867,11 +870,11 @@
 
         // 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;
-        BigInteger f1 = new BigInteger(40, 100, rndSeed.getRandom());
+        BigInteger f1 = new BigInteger(40, 100, random);
         while (found < NUM_CARMICHAELS_TO_TEST) {
             BigInteger k = null;
             BigInteger f2, f3;
             f1 = f1.nextProbablePrime();
             BigInteger[] result = f1.subtract(ONE).divideAndRemainder(SIX);

@@ -894,22 +897,22 @@
             f1 = f1.add(TWO);
         }
 
         // Test some composites that are products of 2 primes
         for (int i=0; i<50; i++) {
-            p1 = BigInteger.probablePrime(100, rndSeed.getRandom());
-            p2 = BigInteger.probablePrime(100, rndSeed.getRandom());
+            p1 = BigInteger.probablePrime(100, random);
+            p2 = BigInteger.probablePrime(100, random);
             c1 = p1.multiply(p2);
             if (c1.isProbablePrime(100)) {
                 System.err.println("Composite failed "+c1.toString(16));
                 failCount++;
             }
         }
 
         for (int i=0; i<4; i++) {
-            p1 = BigInteger.probablePrime(600, rndSeed.getRandom());
-            p2 = BigInteger.probablePrime(600, rndSeed.getRandom());
+            p1 = BigInteger.probablePrime(600, random);
+            p2 = BigInteger.probablePrime(600, random);
             c1 = p1.multiply(p2);
             if (c1.isProbablePrime(100)) {
                 System.err.println("Composite failed "+c1.toString(16));
                 failCount++;
             }

@@ -960,11 +963,11 @@
         }
 
         // 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) {
-            p1 = BigInteger.probablePrime(50 + i, rndSeed.getRandom());
+            p1 = BigInteger.probablePrime(50 + i, random);
             p2 = p1.add(ONE);
             p3 = p1.nextProbablePrime();
             while(p2.compareTo(p3) < 0) {
                 if (p2.isProbablePrime(100)){
                     System.err.println("nextProbablePrime failed");

@@ -1025,11 +1028,11 @@
             }
             f.delete();
         }
 
         for(int i=0; i<10; i++) {
-            BigInteger b1 = fetchNumber(rndSeed.getRandom().nextInt(100));
+            BigInteger b1 = fetchNumber(random.nextInt(100));
             BigInteger b2 = null;
             File f = new File("serialtest");
             try (FileOutputStream fos = new FileOutputStream(f)) {
                 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
                     oos.writeObject(b1);

@@ -1059,12 +1062,10 @@
      * used for call parameters 1, 2, and 3. The SIZE is interpreted as
      * the maximum number of decimal digits that the parameters will have.
      *
      */
     public static void main(String[] args) throws Exception {
-        System.out.println("Random number generator seed = " + rndSeed.getSeed());
-
         // Some variables for sizing test numbers in bits
         int order1 = ORDER_MEDIUM;
         int order2 = ORDER_SMALL;
         int order3 = ORDER_KARATSUBA;
         int order4 = ORDER_TOOM_COOK;

@@ -1132,12 +1133,12 @@
      * numbers, empty BigIntegers, etc.
      *
      * If order is less than 2, order is changed to 2.
      */
     private static BigInteger fetchNumber(int order) {
-        boolean negative = rndSeed.getRandom().nextBoolean();
-        int numType = rndSeed.getRandom().nextInt(7);
+        boolean negative = random.nextBoolean();
+        int numType = random.nextInt(7);
         BigInteger result = null;
         if (order < 2) order = 2;
 
         switch (numType) {
             case 0: // Empty

@@ -1157,38 +1158,38 @@
                 fullBits[0] &= (1 << (8-excessBits)) - 1;
                 result = new BigInteger(1, fullBits);
                 break;
 
             case 3: // One bit in number
-                result = BigInteger.ONE.shiftLeft(rndSeed.getRandom().nextInt(order));
+                result = BigInteger.ONE.shiftLeft(random.nextInt(order));
                 break;
 
             case 4: // Random bit density
                 byte[] val = new byte[(order+7)/8];
-                int iterations = rndSeed.getRandom().nextInt(order);
+                int iterations = random.nextInt(order);
                 for (int i=0; i<iterations; i++) {
-                    int bitIdx = rndSeed.getRandom().nextInt(order);
+                    int bitIdx = random.nextInt(order);
                     val[bitIdx/8] |= 1 << (bitIdx%8);
                 }
                 result = new BigInteger(1, val);
                 break;
             case 5: // Runs of consecutive ones and zeros
                 result = ZERO;
                 int remaining = order;
-                int bit = rndSeed.getRandom().nextInt(2);
+                int bit = random.nextInt(2);
                 while (remaining > 0) {
-                    int runLength = Math.min(remaining, rndSeed.getRandom().nextInt(order));
+                    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;
 
             default: // random bits
-                result = new BigInteger(order, rndSeed.getRandom());
+                result = new BigInteger(order, random);
         }
 
         if (negative)
             result = result.negate();