blob: 3566a1f361970f811ae42ffa987cb0827e251ea5 [file] [log] [blame]
darcy32db4492009-01-26 19:49:26 -08001/*
ohairbf91ea12011-04-06 22:06:11 -07002 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
darcy32db4492009-01-26 19:49:26 -08003 * 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 *
ohair2283b9d2010-05-25 15:58:33 -070019 * 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.
darcy32db4492009-01-26 19:49:26 -080022 */
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
32import java.util.Random;
33import java.math.BigInteger;
34import 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 */
50public 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);
darcye5dbfef2009-12-22 21:48:19 -0800645 BigInteger b2 = null;
darcy32db4492009-01-26 19:49:26 -0800646
647 File f = new File("serialtest");
smarks1dba3592011-02-22 15:34:17 -0800648
649 try (FileOutputStream fos = new FileOutputStream(f)) {
650 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
darcye5dbfef2009-12-22 21:48:19 -0800651 oos.writeObject(b1);
652 oos.flush();
darcye5dbfef2009-12-22 21:48:19 -0800653 }
darcy32db4492009-01-26 19:49:26 -0800654
smarks1dba3592011-02-22 15:34:17 -0800655 try (FileInputStream fis = new FileInputStream(f);
656 ObjectInputStream ois = new ObjectInputStream(fis))
657 {
658 b2 = (BigInteger)ois.readObject();
darcye5dbfef2009-12-22 21:48:19 -0800659 }
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 }
darcy32db4492009-01-26 19:49:26 -0800667 }
668 f.delete();
669 }
670
671 for(int i=0; i<10; i++) {
672 BigInteger b1 = fetchNumber(rnd.nextInt(100));
darcye5dbfef2009-12-22 21:48:19 -0800673 BigInteger b2 = null;
darcy32db4492009-01-26 19:49:26 -0800674 File f = new File("serialtest");
smarks1dba3592011-02-22 15:34:17 -0800675 try (FileOutputStream fos = new FileOutputStream(f)) {
676 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
darcye5dbfef2009-12-22 21:48:19 -0800677 oos.writeObject(b1);
678 oos.flush();
darcye5dbfef2009-12-22 21:48:19 -0800679 }
680
smarks1dba3592011-02-22 15:34:17 -0800681 try (FileInputStream fis = new FileInputStream(f);
682 ObjectInputStream ois = new ObjectInputStream(fis))
683 {
684 b2 = (BigInteger)ois.readObject();
darcye5dbfef2009-12-22 21:48:19 -0800685 }
darcye5dbfef2009-12-22 21:48:19 -0800686 }
darcy32db4492009-01-26 19:49:26 -0800687
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}