1 /*
   2  * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @library /lib/testlibrary/
  27  * @build jdk.testlibrary.*
  28  * @run main BigIntegerTest
  29  * @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225 4837946 4026465 8074460 8078672
  30  * @summary tests methods in BigInteger (use -Dseed=X to set PRNG seed)
  31  * @run main/timeout=400 BigIntegerTest
  32  * @author madbot
  33  * @key randomness
  34  */
  35 
  36 import java.io.File;
  37 import java.io.FileInputStream;
  38 import java.io.FileOutputStream;
  39 import java.io.ObjectInputStream;
  40 import java.io.ObjectOutputStream;
  41 import java.math.BigInteger;
  42 import java.util.Random;
  43 import jdk.testlibrary.RandomFactory;
  44 
  45 /**
  46  * This is a simple test class created to ensure that the results
  47  * generated by BigInteger adhere to certain identities. Passing
  48  * this test is a strong assurance that the BigInteger operations
  49  * are working correctly.
  50  *
  51  * Four arguments may be specified which give the number of
  52  * decimal digits you desire in the four batches of test numbers.
  53  *
  54  * The tests are performed on arrays of random numbers which are
  55  * generated by a Random class as well as special cases which
  56  * throw in boundary numbers such as 0, 1, maximum sized, etc.
  57  *
  58  */
  59 public class BigIntegerTest {
  60     //
  61     // Bit large number thresholds based on the int thresholds
  62     // defined in BigInteger itself:
  63     //
  64     // KARATSUBA_THRESHOLD        = 80  ints = 2560 bits
  65     // TOOM_COOK_THRESHOLD        = 240 ints = 7680 bits
  66     // KARATSUBA_SQUARE_THRESHOLD = 128 ints = 4096 bits
  67     // TOOM_COOK_SQUARE_THRESHOLD = 216 ints = 6912 bits
  68     //
  69     // SCHOENHAGE_BASE_CONVERSION_THRESHOLD = 20 ints = 640 bits
  70     //
  71     // BURNIKEL_ZIEGLER_THRESHOLD = 80  ints = 2560 bits
  72     //
  73     static final int BITS_KARATSUBA = 2560;
  74     static final int BITS_TOOM_COOK = 7680;
  75     static final int BITS_KARATSUBA_SQUARE = 4096;
  76     static final int BITS_TOOM_COOK_SQUARE = 6912;
  77     static final int BITS_SCHOENHAGE_BASE = 640;
  78     static final int BITS_BURNIKEL_ZIEGLER = 2560;
  79     static final int BITS_BURNIKEL_ZIEGLER_OFFSET = 1280;
  80 
  81     static final int ORDER_SMALL = 60;
  82     static final int ORDER_MEDIUM = 100;
  83     // #bits for testing Karatsuba
  84     static final int ORDER_KARATSUBA = 2760;
  85     // #bits for testing Toom-Cook and Burnikel-Ziegler
  86     static final int ORDER_TOOM_COOK = 8000;
  87     // #bits for testing Karatsuba squaring
  88     static final int ORDER_KARATSUBA_SQUARE = 4200;
  89     // #bits for testing Toom-Cook squaring
  90     static final int ORDER_TOOM_COOK_SQUARE = 7000;
  91 
  92     static final int SIZE = 1000; // numbers per batch
  93 
  94     private static Random random = RandomFactory.getRandom();
  95 
  96     static boolean failure = false;
  97 
  98     public static void constructor() {
  99         int failCount = 0;
 100 
 101         // --- guard condition tests for array indexing ---
 102 
 103         int arrayLength = 23;
 104         int halfLength = arrayLength/2;
 105         byte[] array = new byte[arrayLength];
 106         random.nextBytes(array);
 107 
 108         int[][] offLen = new int[][] { // offset, length, num exceptions
 109             {-1, arrayLength, 1},                         // negative offset
 110             {0, arrayLength, 0},                          // OK
 111             {1, arrayLength, 1},                          // length overflow
 112             {arrayLength - 1, 1, 0},                      // OK
 113             {arrayLength, 1, 1},                          // offset overflow
 114             {0, -1, 1},                                   // negative length
 115             {halfLength, arrayLength - halfLength + 1, 1} // length overflow
 116         };
 117 
 118         // two's complement
 119         for (int[] ol : offLen) {
 120             int numExceptions = 0;
 121             try {
 122                 BigInteger bi = new BigInteger(array, ol[0], ol[1]);
 123             } catch (IndexOutOfBoundsException e) {
 124                 numExceptions++;
 125             }
 126             if (numExceptions != ol[2]) {
 127                 System.err.println("IndexOutOfBoundsException did not occur for "
 128                     + " two's complement constructor with parameters offset "
 129                     + ol[0] + " and length " + ol[1]);
 130                 failCount++;
 131             }
 132         }
 133 
 134         // sign-magnitude
 135         for (int[] ol : offLen) {
 136             int numExceptions = 0;
 137             try {
 138                 BigInteger bi = new BigInteger(1, array, ol[0], ol[1]);
 139             } catch (IndexOutOfBoundsException e) {
 140                 numExceptions++;
 141             }
 142             if (numExceptions != ol[2]) {
 143                 System.err.println("IndexOutOfBoundsException did not occur for "
 144                     + " sign-magnitude constructor with parameters offset "
 145                     + ol[0] + " and length " + ol[1]);
 146                 failCount++;
 147             }
 148         }
 149 
 150         // --- tests for creation of zero-valued BigIntegers ---
 151 
 152         byte[] magZeroLength = new byte[0];
 153         for (int signum = -1; signum <= 1; signum++) {
 154             BigInteger bi = new BigInteger(signum, magZeroLength);
 155             if (bi.compareTo(BigInteger.ZERO) != 0) {
 156                 System.err.println("A: Zero length BigInteger != 0 for signum " + signum);
 157                 failCount++;
 158             }
 159         }
 160 
 161         for (int signum = -1; signum <= 1; signum++) {
 162             BigInteger bi = new BigInteger(signum, magZeroLength, 0, 0);
 163             if (bi.compareTo(BigInteger.ZERO) != 0) {
 164                 System.err.println("B: Zero length BigInteger != 0 for signum " + signum);
 165                 failCount++;
 166             }
 167         }
 168 
 169         byte[] magNonZeroLength = new byte[42];
 170         random.nextBytes(magNonZeroLength);
 171         for (int signum = -1; signum <= 1; signum++) {
 172             BigInteger bi = new BigInteger(signum, magNonZeroLength, 0, 0);
 173             if (bi.compareTo(BigInteger.ZERO) != 0) {
 174                 System.err.println("C: Zero length BigInteger != 0 for signum " + signum);
 175                 failCount++;
 176             }
 177         }
 178 
 179         // --- tests for accurate creation of non-zero BigIntegers ---
 180 
 181         for (int i = 0; i < SIZE; i++) {
 182             // create reference value via a different code path from those tested
 183             BigInteger reference = new BigInteger(2 + random.nextInt(336), 4, random);
 184 
 185             byte[] refArray = reference.toByteArray();
 186             int refLen = refArray.length;
 187             int factor = random.nextInt(5);
 188             int objLen = refArray.length + factor*random.nextInt(refArray.length) + 1;
 189             int offset = random.nextInt(objLen - refLen);
 190             byte[] objArray = new byte[objLen];
 191             System.arraycopy(refArray, 0, objArray, offset, refLen);
 192 
 193             BigInteger twosComp = new BigInteger(objArray, offset, refLen);
 194             if (twosComp.compareTo(reference) != 0) {
 195                 System.err.println("Two's-complement BigInteger not equal for offset " +
 196                         offset + " and length " + refLen);
 197                 failCount++;
 198             }
 199 
 200             boolean isNegative = random.nextBoolean();
 201             BigInteger signMag = new BigInteger(isNegative ? -1 : 1, objArray, offset, refLen);
 202             if (signMag.compareTo(isNegative ? reference.negate() : reference) != 0) {
 203                 System.err.println("Sign-magnitude BigInteger not equal for offset " +
 204                         offset + " and length " + refLen);
 205                 failCount++;
 206             }
 207         }
 208 
 209         report("Constructor", failCount);
 210     }
 211 
 212     public static void pow(int order) {
 213         int failCount1 = 0;
 214 
 215         for (int i=0; i<SIZE; i++) {
 216             // Test identity x^power == x*x*x ... *x
 217             int power = random.nextInt(6) + 2;
 218             BigInteger x = fetchNumber(order);
 219             BigInteger y = x.pow(power);
 220             BigInteger z = x;
 221 
 222             for (int j=1; j<power; j++)
 223                 z = z.multiply(x);
 224 
 225             if (!y.equals(z))
 226                 failCount1++;
 227         }
 228         report("pow for " + order + " bits", failCount1);
 229     }
 230 
 231     public static void square(int order) {
 232         int failCount1 = 0;
 233 
 234         for (int i=0; i<SIZE; i++) {
 235             // Test identity x^2 == x*x
 236             BigInteger x  = fetchNumber(order);
 237             BigInteger xx = x.multiply(x);
 238             BigInteger x2 = x.pow(2);
 239 
 240             if (!x2.equals(xx))
 241                 failCount1++;
 242         }
 243         report("square for " + order + " bits", failCount1);
 244     }
 245 
 246     public static void arithmetic(int order) {
 247         int failCount = 0;
 248 
 249         for (int i=0; i<SIZE; i++) {
 250             BigInteger x = fetchNumber(order);
 251             while(x.compareTo(BigInteger.ZERO) != 1)
 252                 x = fetchNumber(order);
 253             BigInteger y = fetchNumber(order/2);
 254             while(x.compareTo(y) == -1)
 255                 y = fetchNumber(order/2);
 256             if (y.equals(BigInteger.ZERO))
 257                 y = y.add(BigInteger.ONE);
 258 
 259             // Test identity ((x/y))*y + x%y - x == 0
 260             // using separate divide() and remainder()
 261             BigInteger baz = x.divide(y);
 262             baz = baz.multiply(y);
 263             baz = baz.add(x.remainder(y));
 264             baz = baz.subtract(x);
 265             if (!baz.equals(BigInteger.ZERO))
 266                 failCount++;
 267         }
 268         report("Arithmetic I for " + order + " bits", failCount);
 269 
 270         failCount = 0;
 271         for (int i=0; i<100; i++) {
 272             BigInteger x = fetchNumber(order);
 273             while(x.compareTo(BigInteger.ZERO) != 1)
 274                 x = fetchNumber(order);
 275             BigInteger y = fetchNumber(order/2);
 276             while(x.compareTo(y) == -1)
 277                 y = fetchNumber(order/2);
 278             if (y.equals(BigInteger.ZERO))
 279                 y = y.add(BigInteger.ONE);
 280 
 281             // Test identity ((x/y))*y + x%y - x == 0
 282             // using divideAndRemainder()
 283             BigInteger baz[] = x.divideAndRemainder(y);
 284             baz[0] = baz[0].multiply(y);
 285             baz[0] = baz[0].add(baz[1]);
 286             baz[0] = baz[0].subtract(x);
 287             if (!baz[0].equals(BigInteger.ZERO))
 288                 failCount++;
 289         }
 290         report("Arithmetic II for " + order + " bits", failCount);
 291     }
 292 
 293     /**
 294      * Sanity test for Karatsuba and 3-way Toom-Cook multiplication.
 295      * For each of the Karatsuba and 3-way Toom-Cook multiplication thresholds,
 296      * construct two factors each with a mag array one element shorter than the
 297      * threshold, and with the most significant bit set and the rest of the bits
 298      * random. Each of these numbers will therefore be below the threshold but
 299      * if shifted left be above the threshold. Call the numbers 'u' and 'v' and
 300      * define random shifts 'a' and 'b' in the range [1,32]. Then we have the
 301      * identity
 302      * <pre>
 303      * (u << a)*(v << b) = (u*v) << (a + b)
 304      * </pre>
 305      * For Karatsuba multiplication, the right hand expression will be evaluated
 306      * using the standard naive algorithm, and the left hand expression using
 307      * the Karatsuba algorithm. For 3-way Toom-Cook multiplication, the right
 308      * hand expression will be evaluated using Karatsuba multiplication, and the
 309      * left hand expression using 3-way Toom-Cook multiplication.
 310      */
 311     public static void multiplyLarge() {
 312         int failCount = 0;
 313 
 314         BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA - 32 - 1);
 315         for (int i=0; i<SIZE; i++) {
 316             BigInteger x = fetchNumber(BITS_KARATSUBA - 32 - 1);
 317             BigInteger u = base.add(x);
 318             int a = 1 + random.nextInt(31);
 319             BigInteger w = u.shiftLeft(a);
 320 
 321             BigInteger y = fetchNumber(BITS_KARATSUBA - 32 - 1);
 322             BigInteger v = base.add(y);
 323             int b = 1 + random.nextInt(32);
 324             BigInteger z = v.shiftLeft(b);
 325 
 326             BigInteger multiplyResult = u.multiply(v).shiftLeft(a + b);
 327             BigInteger karatsubaMultiplyResult = w.multiply(z);
 328 
 329             if (!multiplyResult.equals(karatsubaMultiplyResult)) {
 330                 failCount++;
 331             }
 332         }
 333 
 334         report("multiplyLarge Karatsuba", failCount);
 335 
 336         failCount = 0;
 337         base = base.shiftLeft(BITS_TOOM_COOK - BITS_KARATSUBA);
 338         for (int i=0; i<SIZE; i++) {
 339             BigInteger x = fetchNumber(BITS_TOOM_COOK - 32 - 1);
 340             BigInteger u = base.add(x);
 341             BigInteger u2 = u.shiftLeft(1);
 342             BigInteger y = fetchNumber(BITS_TOOM_COOK - 32 - 1);
 343             BigInteger v = base.add(y);
 344             BigInteger v2 = v.shiftLeft(1);
 345 
 346             BigInteger multiplyResult = u.multiply(v).shiftLeft(2);
 347             BigInteger toomCookMultiplyResult = u2.multiply(v2);
 348 
 349             if (!multiplyResult.equals(toomCookMultiplyResult)) {
 350                 failCount++;
 351             }
 352         }
 353 
 354         report("multiplyLarge Toom-Cook", failCount);
 355     }
 356 
 357     /**
 358      * Sanity test for Karatsuba and 3-way Toom-Cook squaring.
 359      * This test is analogous to {@link AbstractMethodError#multiplyLarge}
 360      * with both factors being equal. The squaring methods will not be tested
 361      * unless the <code>bigInteger.multiply(bigInteger)</code> tests whether
 362      * the parameter is the same instance on which the method is being invoked
 363      * and calls <code>square()</code> accordingly.
 364      */
 365     public static void squareLarge() {
 366         int failCount = 0;
 367 
 368         BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA_SQUARE - 32 - 1);
 369         for (int i=0; i<SIZE; i++) {
 370             BigInteger x = fetchNumber(BITS_KARATSUBA_SQUARE - 32 - 1);
 371             BigInteger u = base.add(x);
 372             int a = 1 + random.nextInt(31);
 373             BigInteger w = u.shiftLeft(a);
 374 
 375             BigInteger squareResult = u.multiply(u).shiftLeft(2*a);
 376             BigInteger karatsubaSquareResult = w.multiply(w);
 377 
 378             if (!squareResult.equals(karatsubaSquareResult)) {
 379                 failCount++;
 380             }
 381         }
 382 
 383         report("squareLarge Karatsuba", failCount);
 384 
 385         failCount = 0;
 386         base = base.shiftLeft(BITS_TOOM_COOK_SQUARE - BITS_KARATSUBA_SQUARE);
 387         for (int i=0; i<SIZE; i++) {
 388             BigInteger x = fetchNumber(BITS_TOOM_COOK_SQUARE - 32 - 1);
 389             BigInteger u = base.add(x);
 390             int a = 1 + random.nextInt(31);
 391             BigInteger w = u.shiftLeft(a);
 392 
 393             BigInteger squareResult = u.multiply(u).shiftLeft(2*a);
 394             BigInteger toomCookSquareResult = w.multiply(w);
 395 
 396             if (!squareResult.equals(toomCookSquareResult)) {
 397                 failCount++;
 398             }
 399         }
 400 
 401         report("squareLarge Toom-Cook", failCount);
 402     }
 403 
 404     /**
 405      * Sanity test for Burnikel-Ziegler division.  The Burnikel-Ziegler division
 406      * algorithm is used when each of the dividend and the divisor has at least
 407      * a specified number of ints in its representation.  This test is based on
 408      * the observation that if {@code w = u*pow(2,a)} and {@code z = v*pow(2,b)}
 409      * where {@code abs(u) > abs(v)} and {@code a > b && b > 0}, then if
 410      * {@code w/z = q1*z + r1} and {@code u/v = q2*v + r2}, then
 411      * {@code q1 = q2*pow(2,a-b)} and {@code r1 = r2*pow(2,b)}.  The test
 412      * ensures that {@code v} is just under the B-Z threshold, that {@code z} is
 413      * over the threshold and {@code w} is much larger than {@code z}. This
 414      * implies that {@code u/v} uses the standard division algorithm and
 415      * {@code w/z} uses the B-Z algorithm.  The results of the two algorithms
 416      * are then compared using the observation described in the foregoing and
 417      * if they are not equal a failure is logged.
 418      */
 419     public static void divideLarge() {
 420         int failCount = 0;
 421 
 422         BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 33);
 423         for (int i=0; i<SIZE; i++) {
 424             BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 34, random);
 425             BigInteger v = base.add(addend);
 426 
 427             BigInteger u = v.multiply(BigInteger.valueOf(2 + random.nextInt(Short.MAX_VALUE - 1)));
 428 
 429             if(random.nextBoolean()) {
 430                 u = u.negate();
 431             }
 432             if(random.nextBoolean()) {
 433                 v = v.negate();
 434             }
 435 
 436             int a = BITS_BURNIKEL_ZIEGLER_OFFSET + random.nextInt(16);
 437             int b = 1 + random.nextInt(16);
 438             BigInteger w = u.multiply(BigInteger.ONE.shiftLeft(a));
 439             BigInteger z = v.multiply(BigInteger.ONE.shiftLeft(b));
 440 
 441             BigInteger[] divideResult = u.divideAndRemainder(v);
 442             divideResult[0] = divideResult[0].multiply(BigInteger.ONE.shiftLeft(a - b));
 443             divideResult[1] = divideResult[1].multiply(BigInteger.ONE.shiftLeft(b));
 444             BigInteger[] bzResult = w.divideAndRemainder(z);
 445 
 446             if (divideResult[0].compareTo(bzResult[0]) != 0 ||
 447                     divideResult[1].compareTo(bzResult[1]) != 0) {
 448                 failCount++;
 449             }
 450         }
 451 
 452         report("divideLarge", failCount);
 453     }
 454 
 455     public static void bitCount() {
 456         int failCount = 0;
 457 
 458         for (int i=0; i<SIZE*10; i++) {
 459             int x = random.nextInt();
 460             BigInteger bigX = BigInteger.valueOf((long)x);
 461             int bit = (x < 0 ? 0 : 1);
 462             int tmp = x, bitCount = 0;
 463             for (int j=0; j<32; j++) {
 464                 bitCount += ((tmp & 1) == bit ? 1 : 0);
 465                 tmp >>= 1;
 466             }
 467 
 468             if (bigX.bitCount() != bitCount) {
 469                 //System.err.println(x+": "+bitCount+", "+bigX.bitCount());
 470                 failCount++;
 471             }
 472         }
 473         report("Bit Count", failCount);
 474     }
 475 
 476     public static void bitLength() {
 477         int failCount = 0;
 478 
 479         for (int i=0; i<SIZE*10; i++) {
 480             int x = random.nextInt();
 481             BigInteger bigX = BigInteger.valueOf((long)x);
 482             int signBit = (x < 0 ? 0x80000000 : 0);
 483             int tmp = x, bitLength, j;
 484             for (j=0; j<32 && (tmp & 0x80000000)==signBit; j++)
 485                 tmp <<= 1;
 486             bitLength = 32 - j;
 487 
 488             if (bigX.bitLength() != bitLength) {
 489                 //System.err.println(x+": "+bitLength+", "+bigX.bitLength());
 490                 failCount++;
 491             }
 492         }
 493 
 494         report("BitLength", failCount);
 495     }
 496 
 497     public static void bitOps(int order) {
 498         int failCount1 = 0, failCount2 = 0, failCount3 = 0;
 499 
 500         for (int i=0; i<SIZE*5; i++) {
 501             BigInteger x = fetchNumber(order);
 502             BigInteger y;
 503 
 504             // Test setBit and clearBit (and testBit)
 505             if (x.signum() < 0) {
 506                 y = BigInteger.valueOf(-1);
 507                 for (int j=0; j<x.bitLength(); j++)
 508                     if (!x.testBit(j))
 509                         y = y.clearBit(j);
 510             } else {
 511                 y = BigInteger.ZERO;
 512                 for (int j=0; j<x.bitLength(); j++)
 513                     if (x.testBit(j))
 514                         y = y.setBit(j);
 515             }
 516             if (!x.equals(y))
 517                 failCount1++;
 518 
 519             // Test flipBit (and testBit)
 520             y = BigInteger.valueOf(x.signum()<0 ? -1 : 0);
 521             for (int j=0; j<x.bitLength(); j++)
 522                 if (x.signum()<0  ^  x.testBit(j))
 523                     y = y.flipBit(j);
 524             if (!x.equals(y))
 525                 failCount2++;
 526         }
 527         report("clearBit/testBit for " + order + " bits", failCount1);
 528         report("flipBit/testBit for " + order + " bits", failCount2);
 529 
 530         for (int i=0; i<SIZE*5; i++) {
 531             BigInteger x = fetchNumber(order);
 532 
 533             // Test getLowestSetBit()
 534             int k = x.getLowestSetBit();
 535             if (x.signum() == 0) {
 536                 if (k != -1)
 537                     failCount3++;
 538             } else {
 539                 BigInteger z = x.and(x.negate());
 540                 int j;
 541                 for (j=0; j<z.bitLength() && !z.testBit(j); j++)
 542                     ;
 543                 if (k != j)
 544                     failCount3++;
 545             }
 546         }
 547         report("getLowestSetBit for " + order + " bits", failCount3);
 548     }
 549 
 550     public static void bitwise(int order) {
 551 
 552         // Test identity x^y == x|y &~ x&y
 553         int failCount = 0;
 554         for (int i=0; i<SIZE; i++) {
 555             BigInteger x = fetchNumber(order);
 556             BigInteger y = fetchNumber(order);
 557             BigInteger z = x.xor(y);
 558             BigInteger w = x.or(y).andNot(x.and(y));
 559             if (!z.equals(w))
 560                 failCount++;
 561         }
 562         report("Logic (^ | & ~) for " + order + " bits", failCount);
 563 
 564         // Test identity x &~ y == ~(~x | y)
 565         failCount = 0;
 566         for (int i=0; i<SIZE; i++) {
 567             BigInteger x = fetchNumber(order);
 568             BigInteger y = fetchNumber(order);
 569             BigInteger z = x.andNot(y);
 570             BigInteger w = x.not().or(y).not();
 571             if (!z.equals(w))
 572                 failCount++;
 573         }
 574         report("Logic (&~ | ~) for " + order + " bits", failCount);
 575     }
 576 
 577     public static void shift(int order) {
 578         int failCount1 = 0;
 579         int failCount2 = 0;
 580         int failCount3 = 0;
 581 
 582         for (int i=0; i<100; i++) {
 583             BigInteger x = fetchNumber(order);
 584             int n = Math.abs(random.nextInt()%200);
 585 
 586             if (!x.shiftLeft(n).equals
 587                 (x.multiply(BigInteger.valueOf(2L).pow(n))))
 588                 failCount1++;
 589 
 590             BigInteger y[] =x.divideAndRemainder(BigInteger.valueOf(2L).pow(n));
 591             BigInteger z = (x.signum()<0 && y[1].signum()!=0
 592                             ? y[0].subtract(BigInteger.ONE)
 593                             : y[0]);
 594 
 595             BigInteger b = x.shiftRight(n);
 596 
 597             if (!b.equals(z)) {
 598                 System.err.println("Input is "+x.toString(2));
 599                 System.err.println("shift is "+n);
 600 
 601                 System.err.println("Divided "+z.toString(2));
 602                 System.err.println("Shifted is "+b.toString(2));
 603                 if (b.toString().equals(z.toString()))
 604                     System.err.println("Houston, we have a problem.");
 605                 failCount2++;
 606             }
 607 
 608             if (!x.shiftLeft(n).shiftRight(n).equals(x))
 609                 failCount3++;
 610         }
 611         report("baz shiftLeft for " + order + " bits", failCount1);
 612         report("baz shiftRight for " + order + " bits", failCount2);
 613         report("baz shiftLeft/Right for " + order + " bits", failCount3);
 614     }
 615 
 616     public static void divideAndRemainder(int order) {
 617         int failCount1 = 0;
 618 
 619         for (int i=0; i<SIZE; i++) {
 620             BigInteger x = fetchNumber(order).abs();
 621             while(x.compareTo(BigInteger.valueOf(3L)) != 1)
 622                 x = fetchNumber(order).abs();
 623             BigInteger z = x.divide(BigInteger.valueOf(2L));
 624             BigInteger y[] = x.divideAndRemainder(x);
 625             if (!y[0].equals(BigInteger.ONE)) {
 626                 failCount1++;
 627                 System.err.println("fail1 x :"+x);
 628                 System.err.println("      y :"+y);
 629             }
 630             else if (!y[1].equals(BigInteger.ZERO)) {
 631                 failCount1++;
 632                 System.err.println("fail2 x :"+x);
 633                 System.err.println("      y :"+y);
 634             }
 635 
 636             y = x.divideAndRemainder(z);
 637             if (!y[0].equals(BigInteger.valueOf(2))) {
 638                 failCount1++;
 639                 System.err.println("fail3 x :"+x);
 640                 System.err.println("      y :"+y);
 641             }
 642         }
 643         report("divideAndRemainder for " + order + " bits", failCount1);
 644     }
 645 
 646     public static void stringConv() {
 647         int failCount = 0;
 648 
 649         // Generic string conversion.
 650         for (int i=0; i<100; i++) {
 651             byte xBytes[] = new byte[Math.abs(random.nextInt())%100+1];
 652             random.nextBytes(xBytes);
 653             BigInteger x = new BigInteger(xBytes);
 654 
 655             for (int radix=Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
 656                 String result = x.toString(radix);
 657                 BigInteger test = new BigInteger(result, radix);
 658                 if (!test.equals(x)) {
 659                     failCount++;
 660                     System.err.println("BigInteger toString: "+x);
 661                     System.err.println("Test: "+test);
 662                     System.err.println(radix);
 663                 }
 664             }
 665         }
 666 
 667         // String conversion straddling the Schoenhage algorithm crossover
 668         // threshold, and at twice and four times the threshold.
 669         for (int k = 0; k <= 2; k++) {
 670             int factor = 1 << k;
 671             int upper = factor * BITS_SCHOENHAGE_BASE + 33;
 672             int lower = upper - 35;
 673 
 674             for (int bits = upper; bits >= lower; bits--) {
 675                 for (int i = 0; i < 50; i++) {
 676                     BigInteger x = BigInteger.ONE.shiftLeft(bits - 1).or(new BigInteger(bits - 2, random));
 677 
 678                     for (int radix = Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
 679                         String result = x.toString(radix);
 680                         BigInteger test = new BigInteger(result, radix);
 681                         if (!test.equals(x)) {
 682                             failCount++;
 683                             System.err.println("BigInteger toString: " + x);
 684                             System.err.println("Test: " + test);
 685                             System.err.println(radix);
 686                         }
 687                     }
 688                 }
 689             }
 690         }
 691 
 692         report("String Conversion", failCount);
 693     }
 694 
 695     public static void byteArrayConv(int order) {
 696         int failCount = 0;
 697 
 698         for (int i=0; i<SIZE; i++) {
 699             BigInteger x = fetchNumber(order);
 700             while (x.equals(BigInteger.ZERO))
 701                 x = fetchNumber(order);
 702             BigInteger y = new BigInteger(x.toByteArray());
 703             if (!x.equals(y)) {
 704                 failCount++;
 705                 System.err.println("orig is "+x);
 706                 System.err.println("new is "+y);
 707             }
 708         }
 709         report("Array Conversion for " + order + " bits", failCount);
 710     }
 711 
 712     public static void modInv(int order) {
 713         int failCount = 0, successCount = 0, nonInvCount = 0;
 714 
 715         for (int i=0; i<SIZE; i++) {
 716             BigInteger x = fetchNumber(order);
 717             while(x.equals(BigInteger.ZERO))
 718                 x = fetchNumber(order);
 719             BigInteger m = fetchNumber(order).abs();
 720             while(m.compareTo(BigInteger.ONE) != 1)
 721                 m = fetchNumber(order).abs();
 722 
 723             try {
 724                 BigInteger inv = x.modInverse(m);
 725                 BigInteger prod = inv.multiply(x).remainder(m);
 726 
 727                 if (prod.signum() == -1)
 728                     prod = prod.add(m);
 729 
 730                 if (prod.equals(BigInteger.ONE))
 731                     successCount++;
 732                 else
 733                     failCount++;
 734             } catch(ArithmeticException e) {
 735                 nonInvCount++;
 736             }
 737         }
 738         report("Modular Inverse for " + order + " bits", failCount);
 739     }
 740 
 741     public static void modExp(int order1, int order2) {
 742         int failCount = 0;
 743 
 744         for (int i=0; i<SIZE/10; i++) {
 745             BigInteger m = fetchNumber(order1).abs();
 746             while(m.compareTo(BigInteger.ONE) != 1)
 747                 m = fetchNumber(order1).abs();
 748             BigInteger base = fetchNumber(order2);
 749             BigInteger exp = fetchNumber(8).abs();
 750 
 751             BigInteger z = base.modPow(exp, m);
 752             BigInteger w = base.pow(exp.intValue()).mod(m);
 753             if (!z.equals(w)) {
 754                 System.err.println("z is "+z);
 755                 System.err.println("w is "+w);
 756                 System.err.println("mod is "+m);
 757                 System.err.println("base is "+base);
 758                 System.err.println("exp is "+exp);
 759                 failCount++;
 760             }
 761         }
 762         report("Exponentiation I for " + order1 + " and " +
 763                order2 + " bits", failCount);
 764     }
 765 
 766     // This test is based on Fermat's theorem
 767     // which is not ideal because base must not be multiple of modulus
 768     // and modulus must be a prime or pseudoprime (Carmichael number)
 769     public static void modExp2(int order) {
 770         int failCount = 0;
 771 
 772         for (int i=0; i<10; i++) {
 773             BigInteger m = new BigInteger(100, 5, random);
 774             while(m.compareTo(BigInteger.ONE) != 1)
 775                 m = new BigInteger(100, 5, random);
 776             BigInteger exp = m.subtract(BigInteger.ONE);
 777             BigInteger base = fetchNumber(order).abs();
 778             while(base.compareTo(m) != -1)
 779                 base = fetchNumber(order).abs();
 780             while(base.equals(BigInteger.ZERO))
 781                 base = fetchNumber(order).abs();
 782 
 783             BigInteger one = base.modPow(exp, m);
 784             if (!one.equals(BigInteger.ONE)) {
 785                 System.err.println("m is "+m);
 786                 System.err.println("base is "+base);
 787                 System.err.println("exp is "+exp);
 788                 failCount++;
 789             }
 790         }
 791         report("Exponentiation II for " + order + " bits", failCount);
 792     }
 793 
 794     private static final int[] mersenne_powers = {
 795         521, 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213, 19937,
 796         21701, 23209, 44497, 86243, 110503, 132049, 216091, 756839, 859433,
 797         1257787, 1398269, 2976221, 3021377, 6972593, 13466917 };
 798 
 799     private static final long[] carmichaels = {
 800       561,1105,1729,2465,2821,6601,8911,10585,15841,29341,41041,46657,52633,
 801       62745,63973,75361,101101,115921,126217,162401,172081,188461,252601,
 802       278545,294409,314821,334153,340561,399001,410041,449065,488881,512461,
 803       225593397919L };
 804 
 805     // Note: testing the larger ones takes too long.
 806     private static final int NUM_MERSENNES_TO_TEST = 7;
 807     // Note: this constant used for computed Carmichaels, not the array above
 808     private static final int NUM_CARMICHAELS_TO_TEST = 5;
 809 
 810     private static final String[] customer_primes = {
 811         "120000000000000000000000000000000019",
 812         "633825300114114700748351603131",
 813         "1461501637330902918203684832716283019651637554291",
 814         "779626057591079617852292862756047675913380626199",
 815         "857591696176672809403750477631580323575362410491",
 816         "910409242326391377348778281801166102059139832131",
 817         "929857869954035706722619989283358182285540127919",
 818         "961301750640481375785983980066592002055764391999",
 819         "1267617700951005189537696547196156120148404630231",
 820         "1326015641149969955786344600146607663033642528339" };
 821 
 822     private static final BigInteger ZERO = BigInteger.ZERO;
 823     private static final BigInteger ONE = BigInteger.ONE;
 824     private static final BigInteger TWO = new BigInteger("2");
 825     private static final BigInteger SIX = new BigInteger("6");
 826     private static final BigInteger TWELVE = new BigInteger("12");
 827     private static final BigInteger EIGHTEEN = new BigInteger("18");
 828 
 829     public static void prime() {
 830         BigInteger p1, p2, c1;
 831         int failCount = 0;
 832 
 833         // Test consistency
 834         for(int i=0; i<10; i++) {
 835             p1 = BigInteger.probablePrime(100, random);
 836             if (!p1.isProbablePrime(100)) {
 837                 System.err.println("Consistency "+p1.toString(16));
 838                 failCount++;
 839             }
 840         }
 841 
 842         // Test some known Mersenne primes (2^n)-1
 843         // The array holds the exponents, not the numbers being tested
 844         for (int i=0; i<NUM_MERSENNES_TO_TEST; i++) {
 845             p1 = new BigInteger("2");
 846             p1 = p1.pow(mersenne_powers[i]);
 847             p1 = p1.subtract(BigInteger.ONE);
 848             if (!p1.isProbablePrime(100)) {
 849                 System.err.println("Mersenne prime "+i+ " failed.");
 850                 failCount++;
 851             }
 852         }
 853 
 854         // Test some primes reported by customers as failing in the past
 855         for (int i=0; i<customer_primes.length; i++) {
 856             p1 = new BigInteger(customer_primes[i]);
 857             if (!p1.isProbablePrime(100)) {
 858                 System.err.println("Customer prime "+i+ " failed.");
 859                 failCount++;
 860             }
 861         }
 862 
 863         // Test some known Carmichael numbers.
 864         for (int i=0; i<carmichaels.length; i++) {
 865             c1 = BigInteger.valueOf(carmichaels[i]);
 866             if(c1.isProbablePrime(100)) {
 867                 System.err.println("Carmichael "+i+ " reported as prime.");
 868                 failCount++;
 869             }
 870         }
 871 
 872         // Test some computed Carmichael numbers.
 873         // Numbers of the form (6k+1)(12k+1)(18k+1) are Carmichael numbers if
 874         // each of the factors is prime
 875         int found = 0;
 876         BigInteger f1 = new BigInteger(40, 100, random);
 877         while (found < NUM_CARMICHAELS_TO_TEST) {
 878             BigInteger k = null;
 879             BigInteger f2, f3;
 880             f1 = f1.nextProbablePrime();
 881             BigInteger[] result = f1.subtract(ONE).divideAndRemainder(SIX);
 882             if (result[1].equals(ZERO)) {
 883                 k = result[0];
 884                 f2 = k.multiply(TWELVE).add(ONE);
 885                 if (f2.isProbablePrime(100)) {
 886                     f3 = k.multiply(EIGHTEEN).add(ONE);
 887                     if (f3.isProbablePrime(100)) {
 888                         c1 = f1.multiply(f2).multiply(f3);
 889                         if (c1.isProbablePrime(100)) {
 890                             System.err.println("Computed Carmichael "
 891                                                +c1.toString(16));
 892                             failCount++;
 893                         }
 894                         found++;
 895                     }
 896                 }
 897             }
 898             f1 = f1.add(TWO);
 899         }
 900 
 901         // Test some composites that are products of 2 primes
 902         for (int i=0; i<50; i++) {
 903             p1 = BigInteger.probablePrime(100, random);
 904             p2 = BigInteger.probablePrime(100, random);
 905             c1 = p1.multiply(p2);
 906             if (c1.isProbablePrime(100)) {
 907                 System.err.println("Composite failed "+c1.toString(16));
 908                 failCount++;
 909             }
 910         }
 911 
 912         for (int i=0; i<4; i++) {
 913             p1 = BigInteger.probablePrime(600, random);
 914             p2 = BigInteger.probablePrime(600, random);
 915             c1 = p1.multiply(p2);
 916             if (c1.isProbablePrime(100)) {
 917                 System.err.println("Composite failed "+c1.toString(16));
 918                 failCount++;
 919             }
 920         }
 921 
 922         report("Prime", failCount);
 923     }
 924 
 925     private static final long[] primesTo100 = {
 926         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
 927     };
 928 
 929     private static final long[] aPrimeSequence = {
 930         1999999003L, 1999999013L, 1999999049L, 1999999061L, 1999999081L,
 931         1999999087L, 1999999093L, 1999999097L, 1999999117L, 1999999121L,
 932         1999999151L, 1999999171L, 1999999207L, 1999999219L, 1999999271L,
 933         1999999321L, 1999999373L, 1999999423L, 1999999439L, 1999999499L,
 934         1999999553L, 1999999559L, 1999999571L, 1999999609L, 1999999613L,
 935         1999999621L, 1999999643L, 1999999649L, 1999999657L, 1999999747L,
 936         1999999763L, 1999999777L, 1999999811L, 1999999817L, 1999999829L,
 937         1999999853L, 1999999861L, 1999999871L, 1999999873
 938     };
 939 
 940     public static void nextProbablePrime() throws Exception {
 941         int failCount = 0;
 942         BigInteger p1, p2, p3;
 943         p1 = p2 = p3 = ZERO;
 944 
 945         // First test nextProbablePrime on the low range starting at zero
 946         for (int i=0; i<primesTo100.length; i++) {
 947             p1 = p1.nextProbablePrime();
 948             if (p1.longValue() != primesTo100[i]) {
 949                 System.err.println("low range primes failed");
 950                 System.err.println("p1 is "+p1);
 951                 System.err.println("expected "+primesTo100[i]);
 952                 failCount++;
 953             }
 954         }
 955 
 956         // Test nextProbablePrime on a relatively small, known prime sequence
 957         p1 = BigInteger.valueOf(aPrimeSequence[0]);
 958         for (int i=1; i<aPrimeSequence.length; i++) {
 959             p1 = p1.nextProbablePrime();
 960             if (p1.longValue() != aPrimeSequence[i]) {
 961                 System.err.println("prime sequence failed");
 962                 failCount++;
 963             }
 964         }
 965 
 966         // Next, pick some large primes, use nextProbablePrime to find the
 967         // next one, and make sure there are no primes in between
 968         for (int i=0; i<100; i+=10) {
 969             p1 = BigInteger.probablePrime(50 + i, random);
 970             p2 = p1.add(ONE);
 971             p3 = p1.nextProbablePrime();
 972             while(p2.compareTo(p3) < 0) {
 973                 if (p2.isProbablePrime(100)){
 974                     System.err.println("nextProbablePrime failed");
 975                     System.err.println("along range "+p1.toString(16));
 976                     System.err.println("to "+p3.toString(16));
 977                     failCount++;
 978                     break;
 979                 }
 980                 p2 = p2.add(ONE);
 981             }
 982         }
 983 
 984         report("nextProbablePrime", failCount);
 985     }
 986 
 987     public static void serialize() throws Exception {
 988         int failCount = 0;
 989 
 990         String bitPatterns[] = {
 991              "ffffffff00000000ffffffff00000000ffffffff00000000",
 992              "ffffffffffffffffffffffff000000000000000000000000",
 993              "ffffffff0000000000000000000000000000000000000000",
 994              "10000000ffffffffffffffffffffffffffffffffffffffff",
 995              "100000000000000000000000000000000000000000000000",
 996              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
 997             "-ffffffff00000000ffffffff00000000ffffffff00000000",
 998             "-ffffffffffffffffffffffff000000000000000000000000",
 999             "-ffffffff0000000000000000000000000000000000000000",
1000             "-10000000ffffffffffffffffffffffffffffffffffffffff",
1001             "-100000000000000000000000000000000000000000000000",
1002             "-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1003         };
1004 
1005         for(int i = 0; i < bitPatterns.length; i++) {
1006             BigInteger b1 = new BigInteger(bitPatterns[i], 16);
1007             BigInteger b2 = null;
1008 
1009             File f = new File("serialtest");
1010 
1011             try (FileOutputStream fos = new FileOutputStream(f)) {
1012                 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
1013                     oos.writeObject(b1);
1014                     oos.flush();
1015                 }
1016 
1017                 try (FileInputStream fis = new FileInputStream(f);
1018                      ObjectInputStream ois = new ObjectInputStream(fis))
1019                 {
1020                     b2 = (BigInteger)ois.readObject();
1021                 }
1022 
1023                 if (!b1.equals(b2) ||
1024                     !b1.equals(b1.or(b2))) {
1025                     failCount++;
1026                     System.err.println("Serialized failed for hex " +
1027                                        b1.toString(16));
1028                 }
1029             }
1030             f.delete();
1031         }
1032 
1033         for(int i=0; i<10; i++) {
1034             BigInteger b1 = fetchNumber(random.nextInt(100));
1035             BigInteger b2 = null;
1036             File f = new File("serialtest");
1037             try (FileOutputStream fos = new FileOutputStream(f)) {
1038                 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
1039                     oos.writeObject(b1);
1040                     oos.flush();
1041                 }
1042 
1043                 try (FileInputStream fis = new FileInputStream(f);
1044                      ObjectInputStream ois = new ObjectInputStream(fis))
1045                 {
1046                     b2 = (BigInteger)ois.readObject();
1047                 }
1048             }
1049 
1050             if (!b1.equals(b2) ||
1051                 !b1.equals(b1.or(b2)))
1052                 failCount++;
1053             f.delete();
1054         }
1055 
1056         report("Serialize", failCount);
1057     }
1058 
1059     /**
1060      * Main to interpret arguments and run several tests.
1061      *
1062      * Up to three arguments may be given to specify the SIZE of BigIntegers
1063      * used for call parameters 1, 2, and 3. The SIZE is interpreted as
1064      * the maximum number of decimal digits that the parameters will have.
1065      *
1066      */
1067     public static void main(String[] args) throws Exception {
1068         // Some variables for sizing test numbers in bits
1069         int order1 = ORDER_MEDIUM;
1070         int order2 = ORDER_SMALL;
1071         int order3 = ORDER_KARATSUBA;
1072         int order4 = ORDER_TOOM_COOK;
1073 
1074         if (args.length >0)
1075             order1 = (int)((Integer.parseInt(args[0]))* 3.333);
1076         if (args.length >1)
1077             order2 = (int)((Integer.parseInt(args[1]))* 3.333);
1078         if (args.length >2)
1079             order3 = (int)((Integer.parseInt(args[2]))* 3.333);
1080         if (args.length >3)
1081             order4 = (int)((Integer.parseInt(args[3]))* 3.333);
1082 
1083         constructor();
1084 
1085         prime();
1086         nextProbablePrime();
1087 
1088         arithmetic(order1);   // small numbers
1089         arithmetic(order3);   // Karatsuba range
1090         arithmetic(order4);   // Toom-Cook / Burnikel-Ziegler range
1091 
1092         divideAndRemainder(order1);   // small numbers
1093         divideAndRemainder(order3);   // Karatsuba range
1094         divideAndRemainder(order4);   // Toom-Cook / Burnikel-Ziegler range
1095 
1096         pow(order1);
1097         pow(order3);
1098         pow(order4);
1099 
1100         square(ORDER_MEDIUM);
1101         square(ORDER_KARATSUBA_SQUARE);
1102         square(ORDER_TOOM_COOK_SQUARE);
1103 
1104         bitCount();
1105         bitLength();
1106         bitOps(order1);
1107         bitwise(order1);
1108 
1109         shift(order1);
1110 
1111         byteArrayConv(order1);
1112 
1113         modInv(order1);   // small numbers
1114         modInv(order3);   // Karatsuba range
1115         modInv(order4);   // Toom-Cook / Burnikel-Ziegler range
1116 
1117         modExp(order1, order2);
1118         modExp2(order1);
1119 
1120         stringConv();
1121         serialize();
1122 
1123         multiplyLarge();
1124         squareLarge();
1125         divideLarge();
1126 
1127         if (failure)
1128             throw new RuntimeException("Failure in BigIntegerTest.");
1129     }
1130 
1131     /*
1132      * Get a random or boundary-case number. This is designed to provide
1133      * a lot of numbers that will find failure points, such as max sized
1134      * numbers, empty BigIntegers, etc.
1135      *
1136      * If order is less than 2, order is changed to 2.
1137      */
1138     private static BigInteger fetchNumber(int order) {
1139         boolean negative = random.nextBoolean();
1140         int numType = random.nextInt(7);
1141         BigInteger result = null;
1142         if (order < 2) order = 2;
1143 
1144         switch (numType) {
1145             case 0: // Empty
1146                 result = BigInteger.ZERO;
1147                 break;
1148 
1149             case 1: // One
1150                 result = BigInteger.ONE;
1151                 break;
1152 
1153             case 2: // All bits set in number
1154                 int numBytes = (order+7)/8;
1155                 byte[] fullBits = new byte[numBytes];
1156                 for(int i=0; i<numBytes; i++)
1157                     fullBits[i] = (byte)0xff;
1158                 int excessBits = 8*numBytes - order;
1159                 fullBits[0] &= (1 << (8-excessBits)) - 1;
1160                 result = new BigInteger(1, fullBits);
1161                 break;
1162 
1163             case 3: // One bit in number
1164                 result = BigInteger.ONE.shiftLeft(random.nextInt(order));
1165                 break;
1166 
1167             case 4: // Random bit density
1168                 byte[] val = new byte[(order+7)/8];
1169                 int iterations = random.nextInt(order);
1170                 for (int i=0; i<iterations; i++) {
1171                     int bitIdx = random.nextInt(order);
1172                     val[bitIdx/8] |= 1 << (bitIdx%8);
1173                 }
1174                 result = new BigInteger(1, val);
1175                 break;
1176             case 5: // Runs of consecutive ones and zeros
1177                 result = ZERO;
1178                 int remaining = order;
1179                 int bit = random.nextInt(2);
1180                 while (remaining > 0) {
1181                     int runLength = Math.min(remaining, random.nextInt(order));
1182                     result = result.shiftLeft(runLength);
1183                     if (bit > 0)
1184                         result = result.add(ONE.shiftLeft(runLength).subtract(ONE));
1185                     remaining -= runLength;
1186                     bit = 1 - bit;
1187                 }
1188                 break;
1189 
1190             default: // random bits
1191                 result = new BigInteger(order, random);
1192         }
1193 
1194         if (negative)
1195             result = result.negate();
1196 
1197         return result;
1198     }
1199 
1200     static void report(String testName, int failCount) {
1201         System.err.println(testName+": " +
1202                            (failCount==0 ? "Passed":"Failed("+failCount+")"));
1203         if (failCount > 0)
1204             failure = true;
1205     }
1206 }