1 /* 2 * Copyright (c) 1998, 2003, 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 * @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225 27 * @summary tests methods in BigInteger 28 * @run main/timeout=400 BigIntegerTest 29 * @author madbot 30 */ 31 32 import java.util.Random; 33 import java.math.BigInteger; 34 import java.io.*; 35 36 /** 37 * This is a simple test class created to ensure that the results 38 * generated by BigInteger adhere to certain identities. Passing 39 * this test is a strong assurance that the BigInteger operations 40 * are working correctly. 41 * 42 * Three arguments may be specified which give the number of 43 * decimal digits you desire in the three batches of test numbers. 44 * 45 * The tests are performed on arrays of random numbers which are 46 * generated by a Random class as well as special cases which 47 * throw in boundary numbers such as 0, 1, maximum sized, etc. 48 * 49 */ 50 public class BigIntegerTest { 51 static Random rnd = new Random(); 52 static int size = 1000; // numbers per batch 53 static boolean failure = false; 54 55 // Some variables for sizing test numbers in bits 56 private static int order1 = 100; 57 private static int order2 = 60; 58 private static int order3 = 30; 59 60 public static void pow() { 61 int failCount1 = 0; 62 63 for (int i=0; i<size; i++) { 64 int power = rnd.nextInt(6) +2; 65 BigInteger x = fetchNumber(order1); 66 BigInteger y = x.pow(power); 67 BigInteger z = x; 68 69 for (int j=1; j<power; j++) 70 z = z.multiply(x); 71 72 if (!y.equals(z)) 73 failCount1++; 74 } 75 report("pow", failCount1); 76 } 77 78 public static void arithmetic() { 79 int failCount = 0; 80 81 for (int i=0; i<size; i++) { 82 BigInteger x = fetchNumber(order1); 83 while(x.compareTo(BigInteger.ZERO) != 1) 84 x = fetchNumber(order1); 85 BigInteger y = fetchNumber(order1/2); 86 while(x.compareTo(y) == -1) 87 y = fetchNumber(order1/2); 88 if (y.equals(BigInteger.ZERO)) 89 y = y.add(BigInteger.ONE); 90 91 BigInteger baz = x.divide(y); 92 baz = baz.multiply(y); 93 baz = baz.add(x.remainder(y)); 94 baz = baz.subtract(x); 95 if (!baz.equals(BigInteger.ZERO)) 96 failCount++; 97 } 98 report("Arithmetic I", failCount); 99 100 failCount = 0; 101 for (int i=0; i<100; i++) { 102 BigInteger x = fetchNumber(order1); 103 while(x.compareTo(BigInteger.ZERO) != 1) 104 x = fetchNumber(order1); 105 BigInteger y = fetchNumber(order1/2); 106 while(x.compareTo(y) == -1) 107 y = fetchNumber(order1/2); 108 if (y.equals(BigInteger.ZERO)) 109 y = y.add(BigInteger.ONE); 110 111 BigInteger baz[] = x.divideAndRemainder(y); 112 baz[0] = baz[0].multiply(y); 113 baz[0] = baz[0].add(baz[1]); 114 baz[0] = baz[0].subtract(x); 115 if (!baz[0].equals(BigInteger.ZERO)) 116 failCount++; 117 } 118 report("Arithmetic II", failCount); 119 } 120 121 public static void bitCount() { 122 int failCount = 0; 123 124 for (int i=0; i<size*10; i++) { 125 int x = rnd.nextInt(); 126 BigInteger bigX = BigInteger.valueOf((long)x); 127 int bit = (x < 0 ? 0 : 1); 128 int tmp = x, bitCount = 0; 129 for (int j=0; j<32; j++) { 130 bitCount += ((tmp & 1) == bit ? 1 : 0); 131 tmp >>= 1; 132 } 133 134 if (bigX.bitCount() != bitCount) { 135 //System.err.println(x+": "+bitCount+", "+bigX.bitCount()); 136 failCount++; 137 } 138 } 139 report("Bit Count", failCount); 140 } 141 142 public static void bitLength() { 143 int failCount = 0; 144 145 for (int i=0; i<size*10; i++) { 146 int x = rnd.nextInt(); 147 BigInteger bigX = BigInteger.valueOf((long)x); 148 int signBit = (x < 0 ? 0x80000000 : 0); 149 int tmp = x, bitLength, j; 150 for (j=0; j<32 && (tmp & 0x80000000)==signBit; j++) 151 tmp <<= 1; 152 bitLength = 32 - j; 153 154 if (bigX.bitLength() != bitLength) { 155 //System.err.println(x+": "+bitLength+", "+bigX.bitLength()); 156 failCount++; 157 } 158 } 159 160 report("BitLength", failCount); 161 } 162 163 public static void bitOps() { 164 int failCount1 = 0, failCount2 = 0, failCount3 = 0; 165 166 for (int i=0; i<size*5; i++) { 167 BigInteger x = fetchNumber(order1); 168 BigInteger y; 169 170 /* Test setBit and clearBit (and testBit) */ 171 if (x.signum() < 0) { 172 y = BigInteger.valueOf(-1); 173 for (int j=0; j<x.bitLength(); j++) 174 if (!x.testBit(j)) 175 y = y.clearBit(j); 176 } else { 177 y = BigInteger.ZERO; 178 for (int j=0; j<x.bitLength(); j++) 179 if (x.testBit(j)) 180 y = y.setBit(j); 181 } 182 if (!x.equals(y)) 183 failCount1++; 184 185 /* Test flipBit (and testBit) */ 186 y = BigInteger.valueOf(x.signum()<0 ? -1 : 0); 187 for (int j=0; j<x.bitLength(); j++) 188 if (x.signum()<0 ^ x.testBit(j)) 189 y = y.flipBit(j); 190 if (!x.equals(y)) 191 failCount2++; 192 } 193 report("clearBit/testBit", failCount1); 194 report("flipBit/testBit", failCount2); 195 196 for (int i=0; i<size*5; i++) { 197 BigInteger x = fetchNumber(order1); 198 199 /* Test getLowestSetBit() */ 200 int k = x.getLowestSetBit(); 201 if (x.signum() == 0) { 202 if (k != -1) 203 failCount3++; 204 } else { 205 BigInteger z = x.and(x.negate()); 206 int j; 207 for (j=0; j<z.bitLength() && !z.testBit(j); j++) 208 ; 209 if (k != j) 210 failCount3++; 211 } 212 } 213 report("getLowestSetBit", failCount3); 214 } 215 216 public static void bitwise() { 217 218 /* Test identity x^y == x|y &~ x&y */ 219 int failCount = 0; 220 for (int i=0; i<size; i++) { 221 BigInteger x = fetchNumber(order1); 222 BigInteger y = fetchNumber(order1); 223 BigInteger z = x.xor(y); 224 BigInteger w = x.or(y).andNot(x.and(y)); 225 if (!z.equals(w)) 226 failCount++; 227 } 228 report("Logic (^ | & ~)", failCount); 229 230 /* Test identity x &~ y == ~(~x | y) */ 231 failCount = 0; 232 for (int i=0; i<size; i++) { 233 BigInteger x = fetchNumber(order1); 234 BigInteger y = fetchNumber(order1); 235 BigInteger z = x.andNot(y); 236 BigInteger w = x.not().or(y).not(); 237 if (!z.equals(w)) 238 failCount++; 239 } 240 report("Logic (&~ | ~)", failCount); 241 } 242 243 public static void shift() { 244 int failCount1 = 0; 245 int failCount2 = 0; 246 int failCount3 = 0; 247 248 for (int i=0; i<100; i++) { 249 BigInteger x = fetchNumber(order1); 250 int n = Math.abs(rnd.nextInt()%200); 251 252 if (!x.shiftLeft(n).equals 253 (x.multiply(BigInteger.valueOf(2L).pow(n)))) 254 failCount1++; 255 256 BigInteger y[] =x.divideAndRemainder(BigInteger.valueOf(2L).pow(n)); 257 BigInteger z = (x.signum()<0 && y[1].signum()!=0 258 ? y[0].subtract(BigInteger.ONE) 259 : y[0]); 260 261 BigInteger b = x.shiftRight(n); 262 263 if (!b.equals(z)) { 264 System.err.println("Input is "+x.toString(2)); 265 System.err.println("shift is "+n); 266 267 System.err.println("Divided "+z.toString(2)); 268 System.err.println("Shifted is "+b.toString(2)); 269 if (b.toString().equals(z.toString())) 270 System.err.println("Houston, we have a problem."); 271 failCount2++; 272 } 273 274 if (!x.shiftLeft(n).shiftRight(n).equals(x)) 275 failCount3++; 276 } 277 report("baz shiftLeft", failCount1); 278 report("baz shiftRight", failCount2); 279 report("baz shiftLeft/Right", failCount3); 280 } 281 282 public static void divideAndRemainder() { 283 int failCount1 = 0; 284 285 for (int i=0; i<size; i++) { 286 BigInteger x = fetchNumber(order1).abs(); 287 while(x.compareTo(BigInteger.valueOf(3L)) != 1) 288 x = fetchNumber(order1).abs(); 289 BigInteger z = x.divide(BigInteger.valueOf(2L)); 290 BigInteger y[] = x.divideAndRemainder(x); 291 if (!y[0].equals(BigInteger.ONE)) { 292 failCount1++; 293 System.err.println("fail1 x :"+x); 294 System.err.println(" y :"+y); 295 } 296 else if (!y[1].equals(BigInteger.ZERO)) { 297 failCount1++; 298 System.err.println("fail2 x :"+x); 299 System.err.println(" y :"+y); 300 } 301 302 y = x.divideAndRemainder(z); 303 if (!y[0].equals(BigInteger.valueOf(2))) { 304 failCount1++; 305 System.err.println("fail3 x :"+x); 306 System.err.println(" y :"+y); 307 } 308 } 309 report("divideAndRemainder I", failCount1); 310 } 311 312 public static void stringConv() { 313 int failCount = 0; 314 315 for (int i=0; i<100; i++) { 316 byte xBytes[] = new byte[Math.abs(rnd.nextInt())%100+1]; 317 rnd.nextBytes(xBytes); 318 BigInteger x = new BigInteger(xBytes); 319 320 for (int radix=2; radix < 37; radix++) { 321 String result = x.toString(radix); 322 BigInteger test = new BigInteger(result, radix); 323 if (!test.equals(x)) { 324 failCount++; 325 System.err.println("BigInteger toString: "+x); 326 System.err.println("Test: "+test); 327 System.err.println(radix); 328 } 329 } 330 } 331 report("String Conversion", failCount); 332 } 333 334 public static void byteArrayConv() { 335 int failCount = 0; 336 337 for (int i=0; i<size; i++) { 338 BigInteger x = fetchNumber(order1); 339 while (x.equals(BigInteger.ZERO)) 340 x = fetchNumber(order1); 341 BigInteger y = new BigInteger(x.toByteArray()); 342 if (!x.equals(y)) { 343 failCount++; 344 System.err.println("orig is "+x); 345 System.err.println("new is "+y); 346 } 347 } 348 report("Array Conversion", failCount); 349 } 350 351 public static void modInv() { 352 int failCount = 0, successCount = 0, nonInvCount = 0; 353 354 for (int i=0; i<size; i++) { 355 BigInteger x = fetchNumber(order1); 356 while(x.equals(BigInteger.ZERO)) 357 x = fetchNumber(order1); 358 BigInteger m = fetchNumber(order1).abs(); 359 while(m.compareTo(BigInteger.ONE) != 1) 360 m = fetchNumber(order1).abs(); 361 362 try { 363 BigInteger inv = x.modInverse(m); 364 BigInteger prod = inv.multiply(x).remainder(m); 365 366 if (prod.signum() == -1) 367 prod = prod.add(m); 368 369 if (prod.equals(BigInteger.ONE)) 370 successCount++; 371 else 372 failCount++; 373 } catch(ArithmeticException e) { 374 nonInvCount++; 375 } 376 } 377 report("Modular Inverse", failCount); 378 } 379 380 public static void modExp() { 381 int failCount = 0; 382 383 for (int i=0; i<size/10; i++) { 384 BigInteger m = fetchNumber(order1).abs(); 385 while(m.compareTo(BigInteger.ONE) != 1) 386 m = fetchNumber(order1).abs(); 387 BigInteger base = fetchNumber(order2); 388 BigInteger exp = fetchNumber(8).abs(); 389 390 BigInteger z = base.modPow(exp, m); 391 BigInteger w = base.pow(exp.intValue()).mod(m); 392 if (!z.equals(w)) { 393 System.err.println("z is "+z); 394 System.err.println("w is "+w); 395 System.err.println("mod is "+m); 396 System.err.println("base is "+base); 397 System.err.println("exp is "+exp); 398 failCount++; 399 } 400 } 401 report("Exponentiation I", failCount); 402 } 403 404 // This test is based on Fermat's theorem 405 // which is not ideal because base must not be multiple of modulus 406 // and modulus must be a prime or pseudoprime (Carmichael number) 407 public static void modExp2() { 408 int failCount = 0; 409 410 for (int i=0; i<10; i++) { 411 BigInteger m = new BigInteger(100, 5, rnd); 412 while(m.compareTo(BigInteger.ONE) != 1) 413 m = new BigInteger(100, 5, rnd); 414 BigInteger exp = m.subtract(BigInteger.ONE); 415 BigInteger base = fetchNumber(order1).abs(); 416 while(base.compareTo(m) != -1) 417 base = fetchNumber(order1).abs(); 418 while(base.equals(BigInteger.ZERO)) 419 base = fetchNumber(order1).abs(); 420 421 BigInteger one = base.modPow(exp, m); 422 if (!one.equals(BigInteger.ONE)) { 423 System.err.println("m is "+m); 424 System.err.println("base is "+base); 425 System.err.println("exp is "+exp); 426 failCount++; 427 } 428 } 429 report("Exponentiation II", failCount); 430 } 431 432 private static final int[] mersenne_powers = { 433 521, 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213, 19937, 434 21701, 23209, 44497, 86243, 110503, 132049, 216091, 756839, 859433, 435 1257787, 1398269, 2976221, 3021377, 6972593, 13466917 }; 436 437 private static final long[] carmichaels = { 438 561,1105,1729,2465,2821,6601,8911,10585,15841,29341,41041,46657,52633, 439 62745,63973,75361,101101,115921,126217,162401,172081,188461,252601, 440 278545,294409,314821,334153,340561,399001,410041,449065,488881,512461, 441 225593397919L }; 442 443 // Note: testing the larger ones takes too long. 444 private static final int NUM_MERSENNES_TO_TEST = 7; 445 // Note: this constant used for computed Carmichaels, not the array above 446 private static final int NUM_CARMICHAELS_TO_TEST = 5; 447 448 private static final String[] customer_primes = { 449 "120000000000000000000000000000000019", 450 "633825300114114700748351603131", 451 "1461501637330902918203684832716283019651637554291", 452 "779626057591079617852292862756047675913380626199", 453 "857591696176672809403750477631580323575362410491", 454 "910409242326391377348778281801166102059139832131", 455 "929857869954035706722619989283358182285540127919", 456 "961301750640481375785983980066592002055764391999", 457 "1267617700951005189537696547196156120148404630231", 458 "1326015641149969955786344600146607663033642528339" }; 459 460 private static final BigInteger ZERO = BigInteger.ZERO; 461 private static final BigInteger ONE = BigInteger.ONE; 462 private static final BigInteger TWO = new BigInteger("2"); 463 private static final BigInteger SIX = new BigInteger("6"); 464 private static final BigInteger TWELVE = new BigInteger("12"); 465 private static final BigInteger EIGHTEEN = new BigInteger("18"); 466 467 public static void prime() { 468 BigInteger p1, p2, c1; 469 int failCount = 0; 470 471 // Test consistency 472 for(int i=0; i<10; i++) { 473 p1 = BigInteger.probablePrime(100, rnd); 474 if (!p1.isProbablePrime(100)) { 475 System.err.println("Consistency "+p1.toString(16)); 476 failCount++; 477 } 478 } 479 480 // Test some known Mersenne primes (2^n)-1 481 // The array holds the exponents, not the numbers being tested 482 for (int i=0; i<NUM_MERSENNES_TO_TEST; i++) { 483 p1 = new BigInteger("2"); 484 p1 = p1.pow(mersenne_powers[i]); 485 p1 = p1.subtract(BigInteger.ONE); 486 if (!p1.isProbablePrime(100)) { 487 System.err.println("Mersenne prime "+i+ " failed."); 488 failCount++; 489 } 490 } 491 492 // Test some primes reported by customers as failing in the past 493 for (int i=0; i<customer_primes.length; i++) { 494 p1 = new BigInteger(customer_primes[i]); 495 if (!p1.isProbablePrime(100)) { 496 System.err.println("Customer prime "+i+ " failed."); 497 failCount++; 498 } 499 } 500 501 // Test some known Carmichael numbers. 502 for (int i=0; i<carmichaels.length; i++) { 503 c1 = BigInteger.valueOf(carmichaels[i]); 504 if(c1.isProbablePrime(100)) { 505 System.err.println("Carmichael "+i+ " reported as prime."); 506 failCount++; 507 } 508 } 509 510 // Test some computed Carmichael numbers. 511 // Numbers of the form (6k+1)(12k+1)(18k+1) are Carmichael numbers if 512 // each of the factors is prime 513 int found = 0; 514 BigInteger f1 = new BigInteger(40, 100, rnd); 515 while (found < NUM_CARMICHAELS_TO_TEST) { 516 BigInteger k = null; 517 BigInteger f2, f3; 518 f1 = f1.nextProbablePrime(); 519 BigInteger[] result = f1.subtract(ONE).divideAndRemainder(SIX); 520 if (result[1].equals(ZERO)) { 521 k = result[0]; 522 f2 = k.multiply(TWELVE).add(ONE); 523 if (f2.isProbablePrime(100)) { 524 f3 = k.multiply(EIGHTEEN).add(ONE); 525 if (f3.isProbablePrime(100)) { 526 c1 = f1.multiply(f2).multiply(f3); 527 if (c1.isProbablePrime(100)) { 528 System.err.println("Computed Carmichael " 529 +c1.toString(16)); 530 failCount++; 531 } 532 found++; 533 } 534 } 535 } 536 f1 = f1.add(TWO); 537 } 538 539 // Test some composites that are products of 2 primes 540 for (int i=0; i<50; i++) { 541 p1 = BigInteger.probablePrime(100, rnd); 542 p2 = BigInteger.probablePrime(100, rnd); 543 c1 = p1.multiply(p2); 544 if (c1.isProbablePrime(100)) { 545 System.err.println("Composite failed "+c1.toString(16)); 546 failCount++; 547 } 548 } 549 550 for (int i=0; i<4; i++) { 551 p1 = BigInteger.probablePrime(600, rnd); 552 p2 = BigInteger.probablePrime(600, rnd); 553 c1 = p1.multiply(p2); 554 if (c1.isProbablePrime(100)) { 555 System.err.println("Composite failed "+c1.toString(16)); 556 failCount++; 557 } 558 } 559 560 report("Prime", failCount); 561 } 562 563 private static final long[] primesTo100 = { 564 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 565 }; 566 567 private static final long[] aPrimeSequence = { 568 1999999003L, 1999999013L, 1999999049L, 1999999061L, 1999999081L, 569 1999999087L, 1999999093L, 1999999097L, 1999999117L, 1999999121L, 570 1999999151L, 1999999171L, 1999999207L, 1999999219L, 1999999271L, 571 1999999321L, 1999999373L, 1999999423L, 1999999439L, 1999999499L, 572 1999999553L, 1999999559L, 1999999571L, 1999999609L, 1999999613L, 573 1999999621L, 1999999643L, 1999999649L, 1999999657L, 1999999747L, 574 1999999763L, 1999999777L, 1999999811L, 1999999817L, 1999999829L, 575 1999999853L, 1999999861L, 1999999871L, 1999999873 576 }; 577 578 public static void nextProbablePrime() throws Exception { 579 int failCount = 0; 580 BigInteger p1, p2, p3; 581 p1 = p2 = p3 = ZERO; 582 583 // First test nextProbablePrime on the low range starting at zero 584 for (int i=0; i<primesTo100.length; i++) { 585 p1 = p1.nextProbablePrime(); 586 if (p1.longValue() != primesTo100[i]) { 587 System.err.println("low range primes failed"); 588 System.err.println("p1 is "+p1); 589 System.err.println("expected "+primesTo100[i]); 590 failCount++; 591 } 592 } 593 594 // Test nextProbablePrime on a relatively small, known prime sequence 595 p1 = BigInteger.valueOf(aPrimeSequence[0]); 596 for (int i=1; i<aPrimeSequence.length; i++) { 597 p1 = p1.nextProbablePrime(); 598 if (p1.longValue() != aPrimeSequence[i]) { 599 System.err.println("prime sequence failed"); 600 failCount++; 601 } 602 } 603 604 // Next, pick some large primes, use nextProbablePrime to find the 605 // next one, and make sure there are no primes in between 606 for (int i=0; i<100; i+=10) { 607 p1 = BigInteger.probablePrime(50 + i, rnd); 608 p2 = p1.add(ONE); 609 p3 = p1.nextProbablePrime(); 610 while(p2.compareTo(p3) < 0) { 611 if (p2.isProbablePrime(100)){ 612 System.err.println("nextProbablePrime failed"); 613 System.err.println("along range "+p1.toString(16)); 614 System.err.println("to "+p3.toString(16)); 615 failCount++; 616 break; 617 } 618 p2 = p2.add(ONE); 619 } 620 } 621 622 report("nextProbablePrime", failCount); 623 } 624 625 public static void serialize() throws Exception { 626 int failCount = 0; 627 628 String bitPatterns[] = { 629 "ffffffff00000000ffffffff00000000ffffffff00000000", 630 "ffffffffffffffffffffffff000000000000000000000000", 631 "ffffffff0000000000000000000000000000000000000000", 632 "10000000ffffffffffffffffffffffffffffffffffffffff", 633 "100000000000000000000000000000000000000000000000", 634 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 635 "-ffffffff00000000ffffffff00000000ffffffff00000000", 636 "-ffffffffffffffffffffffff000000000000000000000000", 637 "-ffffffff0000000000000000000000000000000000000000", 638 "-10000000ffffffffffffffffffffffffffffffffffffffff", 639 "-100000000000000000000000000000000000000000000000", 640 "-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 641 }; 642 643 for(int i = 0; i < bitPatterns.length; i++) { 644 BigInteger b1 = new BigInteger(bitPatterns[i], 16); 645 BigInteger b2 = null; 646 647 File f = new File("serialtest"); 648 649 try (FileOutputStream fos = new FileOutputStream(f)) { 650 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) { 651 oos.writeObject(b1); 652 oos.flush(); 653 } 654 655 try (FileInputStream fis = new FileInputStream(f); 656 ObjectInputStream ois = new ObjectInputStream(fis)) 657 { 658 b2 = (BigInteger)ois.readObject(); 659 } 660 661 if (!b1.equals(b2) || 662 !b1.equals(b1.or(b2))) { 663 failCount++; 664 System.err.println("Serialized failed for hex " + 665 b1.toString(16)); 666 } 667 } 668 f.delete(); 669 } 670 671 for(int i=0; i<10; i++) { 672 BigInteger b1 = fetchNumber(rnd.nextInt(100)); 673 BigInteger b2 = null; 674 File f = new File("serialtest"); 675 try (FileOutputStream fos = new FileOutputStream(f)) { 676 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) { 677 oos.writeObject(b1); 678 oos.flush(); 679 } 680 681 try (FileInputStream fis = new FileInputStream(f); 682 ObjectInputStream ois = new ObjectInputStream(fis)) 683 { 684 b2 = (BigInteger)ois.readObject(); 685 } 686 } 687 688 if (!b1.equals(b2) || 689 !b1.equals(b1.or(b2))) 690 failCount++; 691 f.delete(); 692 } 693 694 report("Serialize", failCount); 695 } 696 697 /** 698 * Main to interpret arguments and run several tests. 699 * 700 * Up to three arguments may be given to specify the size of BigIntegers 701 * used for call parameters 1, 2, and 3. The size is interpreted as 702 * the maximum number of decimal digits that the parameters will have. 703 * 704 */ 705 public static void main(String[] args) throws Exception { 706 707 if (args.length >0) 708 order1 = (int)((Integer.parseInt(args[0]))* 3.333); 709 if (args.length >1) 710 order2 = (int)((Integer.parseInt(args[1]))* 3.333); 711 if (args.length >2) 712 order3 = (int)((Integer.parseInt(args[2]))* 3.333); 713 714 prime(); 715 nextProbablePrime(); 716 717 arithmetic(); 718 divideAndRemainder(); 719 pow(); 720 721 bitCount(); 722 bitLength(); 723 bitOps(); 724 bitwise(); 725 726 shift(); 727 728 byteArrayConv(); 729 730 modInv(); 731 modExp(); 732 modExp2(); 733 734 stringConv(); 735 serialize(); 736 737 if (failure) 738 throw new RuntimeException("Failure in BigIntegerTest."); 739 } 740 741 /* 742 * Get a random or boundary-case number. This is designed to provide 743 * a lot of numbers that will find failure points, such as max sized 744 * numbers, empty BigIntegers, etc. 745 * 746 * If order is less than 2, order is changed to 2. 747 */ 748 private static BigInteger fetchNumber(int order) { 749 boolean negative = rnd.nextBoolean(); 750 int numType = rnd.nextInt(6); 751 BigInteger result = null; 752 if (order < 2) order = 2; 753 754 switch (numType) { 755 case 0: // Empty 756 result = BigInteger.ZERO; 757 break; 758 759 case 1: // One 760 result = BigInteger.ONE; 761 break; 762 763 case 2: // All bits set in number 764 int numBytes = (order+7)/8; 765 byte[] fullBits = new byte[numBytes]; 766 for(int i=0; i<numBytes; i++) 767 fullBits[i] = (byte)0xff; 768 int excessBits = 8*numBytes - order; 769 fullBits[0] &= (1 << (8-excessBits)) - 1; 770 result = new BigInteger(1, fullBits); 771 break; 772 773 case 3: // One bit in number 774 result = BigInteger.ONE.shiftLeft(rnd.nextInt(order)); 775 break; 776 777 case 4: // Random bit density 778 int iterations = rnd.nextInt(order-1); 779 result = BigInteger.ONE.shiftLeft(rnd.nextInt(order)); 780 for(int i=0; i<iterations; i++) { 781 BigInteger temp = BigInteger.ONE.shiftLeft( 782 rnd.nextInt(order)); 783 result = result.or(temp); 784 } 785 break; 786 787 default: // random bits 788 result = new BigInteger(order, rnd); 789 } 790 791 if (negative) 792 result = result.negate(); 793 794 return result; 795 } 796 797 static void report(String testName, int failCount) { 798 System.err.println(testName+": " + 799 (failCount==0 ? "Passed":"Failed("+failCount+")")); 800 if (failCount > 0) 801 failure = true; 802 } 803 }