test/java/math/BigInteger/BigIntegerTest.java

Print this page
rev 7474 : 4641897: Faster string conversion of large integers
Summary: Accelerate conversion to string by means of Schoenhage recursive base conversion.
Reviewed-by: bpb
Contributed-by: Alan Eliasen <eliasen@mindspring.com>


  44  * are working correctly.
  45  *
  46  * Three arguments may be specified which give the number of
  47  * decimal digits you desire in the three batches of test numbers.
  48  *
  49  * The tests are performed on arrays of random numbers which are
  50  * generated by a Random class as well as special cases which
  51  * throw in boundary numbers such as 0, 1, maximum sized, etc.
  52  *
  53  */
  54 public class BigIntegerTest {
  55     //
  56     // Bit large number thresholds based on the int thresholds
  57     // defined in BigInteger itself:
  58     //
  59     // KARATSUBA_THRESHOLD        = 50  ints = 1600 bits
  60     // TOOM_COOK_THRESHOLD        = 75  ints = 2400 bits
  61     // KARATSUBA_SQUARE_THRESHOLD = 90  ints = 2880 bits
  62     // TOOM_COOK_SQUARE_THRESHOLD = 140 ints = 4480 bits
  63     //


  64     static final int BITS_KARATSUBA = 1600;
  65     static final int BITS_TOOM_COOK = 2400;
  66     static final int BITS_KARATSUBA_SQUARE = 2880;
  67     static final int BITS_TOOM_COOK_SQUARE = 4480;

  68 
  69     static final int ORDER_SMALL = 60;
  70     static final int ORDER_MEDIUM = 100;
  71     // #bits for testing Karatsuba and Burnikel-Ziegler
  72     static final int ORDER_KARATSUBA = 1800;
  73     // #bits for testing Toom-Cook
  74     static final int ORDER_TOOM_COOK = 3000;
  75     // #bits for testing Karatsuba squaring
  76     static final int ORDER_KARATSUBA_SQUARE = 3200;
  77     // #bits for testing Toom-Cook squaring
  78     static final int ORDER_TOOM_COOK_SQUARE = 4600;
  79 
  80     static Random rnd = new Random();
  81     static int size = 1000; // numbers per batch
  82     static boolean failure = false;
  83 
  84     public static void pow(int order) {
  85         int failCount1 = 0;
  86 
  87         for (int i=0; i<size; i++) {


 450             }
 451             else if (!y[1].equals(BigInteger.ZERO)) {
 452                 failCount1++;
 453                 System.err.println("fail2 x :"+x);
 454                 System.err.println("      y :"+y);
 455             }
 456 
 457             y = x.divideAndRemainder(z);
 458             if (!y[0].equals(BigInteger.valueOf(2))) {
 459                 failCount1++;
 460                 System.err.println("fail3 x :"+x);
 461                 System.err.println("      y :"+y);
 462             }
 463         }
 464         report("divideAndRemainder for " + order + " bits", failCount1);
 465     }
 466 
 467     public static void stringConv() {
 468         int failCount = 0;
 469 

 470         for (int i=0; i<100; i++) {
 471             byte xBytes[] = new byte[Math.abs(rnd.nextInt())%100+1];
 472             rnd.nextBytes(xBytes);
 473             BigInteger x = new BigInteger(xBytes);
 474 
 475             for (int radix=2; radix < 37; radix++) {
 476                 String result = x.toString(radix);
 477                 BigInteger test = new BigInteger(result, radix);
 478                 if (!test.equals(x)) {
 479                     failCount++;
 480                     System.err.println("BigInteger toString: "+x);
 481                     System.err.println("Test: "+test);
 482                     System.err.println(radix);
 483                 }
 484             }
 485         }




























 486         report("String Conversion", failCount);
 487     }
 488 
 489     public static void byteArrayConv(int order) {
 490         int failCount = 0;
 491 
 492         for (int i=0; i<size; i++) {
 493             BigInteger x = fetchNumber(order);
 494             while (x.equals(BigInteger.ZERO))
 495                 x = fetchNumber(order);
 496             BigInteger y = new BigInteger(x.toByteArray());
 497             if (!x.equals(y)) {
 498                 failCount++;
 499                 System.err.println("orig is "+x);
 500                 System.err.println("new is "+y);
 501             }
 502         }
 503         report("Array Conversion for " + order + " bits", failCount);
 504     }
 505 




  44  * are working correctly.
  45  *
  46  * Three arguments may be specified which give the number of
  47  * decimal digits you desire in the three batches of test numbers.
  48  *
  49  * The tests are performed on arrays of random numbers which are
  50  * generated by a Random class as well as special cases which
  51  * throw in boundary numbers such as 0, 1, maximum sized, etc.
  52  *
  53  */
  54 public class BigIntegerTest {
  55     //
  56     // Bit large number thresholds based on the int thresholds
  57     // defined in BigInteger itself:
  58     //
  59     // KARATSUBA_THRESHOLD        = 50  ints = 1600 bits
  60     // TOOM_COOK_THRESHOLD        = 75  ints = 2400 bits
  61     // KARATSUBA_SQUARE_THRESHOLD = 90  ints = 2880 bits
  62     // TOOM_COOK_SQUARE_THRESHOLD = 140 ints = 4480 bits
  63     //
  64     // SCHOENHAGE_BASE_CONVERSION_THRESHOLD = 8 ints = 256 bits
  65     //
  66     static final int BITS_KARATSUBA = 1600;
  67     static final int BITS_TOOM_COOK = 2400;
  68     static final int BITS_KARATSUBA_SQUARE = 2880;
  69     static final int BITS_TOOM_COOK_SQUARE = 4480;
  70     static final int BITS_SCHOENHAGE_BASE = 256;
  71 
  72     static final int ORDER_SMALL = 60;
  73     static final int ORDER_MEDIUM = 100;
  74     // #bits for testing Karatsuba and Burnikel-Ziegler
  75     static final int ORDER_KARATSUBA = 1800;
  76     // #bits for testing Toom-Cook
  77     static final int ORDER_TOOM_COOK = 3000;
  78     // #bits for testing Karatsuba squaring
  79     static final int ORDER_KARATSUBA_SQUARE = 3200;
  80     // #bits for testing Toom-Cook squaring
  81     static final int ORDER_TOOM_COOK_SQUARE = 4600;
  82 
  83     static Random rnd = new Random();
  84     static int size = 1000; // numbers per batch
  85     static boolean failure = false;
  86 
  87     public static void pow(int order) {
  88         int failCount1 = 0;
  89 
  90         for (int i=0; i<size; i++) {


 453             }
 454             else if (!y[1].equals(BigInteger.ZERO)) {
 455                 failCount1++;
 456                 System.err.println("fail2 x :"+x);
 457                 System.err.println("      y :"+y);
 458             }
 459 
 460             y = x.divideAndRemainder(z);
 461             if (!y[0].equals(BigInteger.valueOf(2))) {
 462                 failCount1++;
 463                 System.err.println("fail3 x :"+x);
 464                 System.err.println("      y :"+y);
 465             }
 466         }
 467         report("divideAndRemainder for " + order + " bits", failCount1);
 468     }
 469 
 470     public static void stringConv() {
 471         int failCount = 0;
 472 
 473         // Generic string conversion.
 474         for (int i=0; i<100; i++) {
 475             byte xBytes[] = new byte[Math.abs(rnd.nextInt())%100+1];
 476             rnd.nextBytes(xBytes);
 477             BigInteger x = new BigInteger(xBytes);
 478 
 479             for (int radix=Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
 480                 String result = x.toString(radix);
 481                 BigInteger test = new BigInteger(result, radix);
 482                 if (!test.equals(x)) {
 483                     failCount++;
 484                     System.err.println("BigInteger toString: "+x);
 485                     System.err.println("Test: "+test);
 486                     System.err.println(radix);
 487                 }
 488             }
 489         }
 490 
 491         // String conversion straddling the Schoenhage algorithm crossover
 492         // threshold, and at twice and four times the threshold.
 493         for (int k = 0; k <= 2; k++) {
 494             int factor = 1 << k;
 495             int upper = factor * BITS_SCHOENHAGE_BASE + 33;
 496             int lower = upper - 35;
 497 
 498             for (int bits = upper; bits >= lower; bits--) {
 499                 for (int i = 0; i < 50; i++) {
 500                     BigInteger x = BigInteger.ONE.shiftLeft(bits - 1);
 501                     BigInteger y = new BigInteger(bits - 2, rnd);
 502                     x = x.or(y);
 503 
 504                     for (int radix = Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
 505                         String result = x.toString(radix);
 506                         BigInteger test = new BigInteger(result, radix);
 507                         if (!test.equals(x)) {
 508                             failCount++;
 509                             System.err.println("BigInteger toString: " + x);
 510                             System.err.println("Test: " + test);
 511                             System.err.println(radix);
 512                         }
 513                     }
 514                 }
 515             }
 516         }
 517 
 518         report("String Conversion", failCount);
 519     }
 520 
 521     public static void byteArrayConv(int order) {
 522         int failCount = 0;
 523 
 524         for (int i=0; i<size; i++) {
 525             BigInteger x = fetchNumber(order);
 526             while (x.equals(BigInteger.ZERO))
 527                 x = fetchNumber(order);
 528             BigInteger y = new BigInteger(x.toByteArray());
 529             if (!x.equals(y)) {
 530                 failCount++;
 531                 System.err.println("orig is "+x);
 532                 System.err.println("new is "+y);
 533             }
 534         }
 535         report("Array Conversion for " + order + " bits", failCount);
 536     }
 537