test/java/math/BigInteger/BigIntegerTest.java

Print this page
rev 12826 : 8032027: Add BigInteger square root methods
Summary: Add sqrt() and sqrtAndReminder() using Newton iteration
Reviewed-by: XXX


   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:


 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))


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();




   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 8032027
  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.BigDecimal;
  42 import java.math.BigInteger;
  43 import java.util.Random;
  44 import java.util.stream.DoubleStream;
  45 import java.util.stream.IntStream;
  46 import java.util.stream.LongStream;
  47 import jdk.testlibrary.RandomFactory;
  48 
  49 /**
  50  * This is a simple test class created to ensure that the results
  51  * generated by BigInteger adhere to certain identities. Passing
  52  * this test is a strong assurance that the BigInteger operations
  53  * are working correctly.
  54  *
  55  * Four arguments may be specified which give the number of
  56  * decimal digits you desire in the four batches of test numbers.
  57  *
  58  * The tests are performed on arrays of random numbers which are
  59  * generated by a Random class as well as special cases which
  60  * throw in boundary numbers such as 0, 1, maximum sized, etc.
  61  *
  62  */
  63 public class BigIntegerTest {
  64     //
  65     // Bit large number thresholds based on the int thresholds
  66     // defined in BigInteger itself:


 230                 failCount1++;
 231         }
 232         report("pow for " + order + " bits", failCount1);
 233     }
 234 
 235     public static void square(int order) {
 236         int failCount1 = 0;
 237 
 238         for (int i=0; i<SIZE; i++) {
 239             // Test identity x^2 == x*x
 240             BigInteger x  = fetchNumber(order);
 241             BigInteger xx = x.multiply(x);
 242             BigInteger x2 = x.pow(2);
 243 
 244             if (!x2.equals(xx))
 245                 failCount1++;
 246         }
 247         report("square for " + order + " bits", failCount1);
 248     }
 249 
 250     private static void fail(String msg) {
 251         System.err.println(msg);
 252         failure = true;
 253     }
 254 
 255     private static void fail(String msg, Object expected, Object actual) {
 256         System.err.println(msg + " - expected: " + expected + ", actual: " + actual);
 257         failure = true;
 258     }
 259 
 260     private static void squareRootSmall() {
 261         // A negative value should cause an exception.
 262         BigInteger n = BigInteger.ONE.negate();
 263         BigInteger s;
 264         try {
 265             s = n.sqrt();
 266             // If sqrt() does not throw an exception that is a failure.
 267             fail("sqrt() of negative number did not throw an exception");
 268         } catch (ArithmeticException expected) {
 269             // A negative value should cause an exception and is not a failure.
 270         }
 271 
 272         // A zero value should return BigInteger.ZERO.
 273         if (!BigInteger.valueOf(0).sqrt().equals(BigInteger.ZERO)) {
 274             fail("sqrt(0) != BigInteger.ZERO");
 275         }
 276 
 277         // 1 <= value < 4 should return BigInteger.ONE.
 278         long[] smalls = new long[] {1, 2, 3};
 279         for (long small : smalls) {
 280             if (!BigInteger.valueOf(small).sqrt().equals(BigInteger.ONE)) {
 281                 fail("sqrt("+small+") != 1");
 282             }
 283         }
 284     }
 285 
 286     private static void squareRootInt() {
 287         IntStream ints = random.ints(SIZE, 4, Integer.MAX_VALUE);
 288         ints.forEach(i -> {
 289             BigInteger n = BigInteger.valueOf(i);
 290             BigInteger n2 = n.pow(2);
 291 
 292             // square root of n^2 -> n
 293             BigInteger actual = n2.sqrt();
 294             if (actual.compareTo(n) != 0) {
 295                 fail("sqrt(int)", n, actual);
 296             }
 297 
 298             // square root of n^2 + 1 -> n
 299             BigInteger n2up = n2.add(BigInteger.ONE);
 300             actual = n2up.sqrt();
 301             if (actual.compareTo(n) != 0) {
 302                 fail("sqrt(int)", n, actual);
 303             }
 304 
 305             // square root of (n + 1)^2 - 1 -> n
 306             BigInteger up = n.add(BigInteger.ONE).pow(2).subtract(BigInteger.ONE);
 307             actual = up.sqrt();
 308             if (actual.compareTo(n) != 0) {
 309                 fail("sqrt(int)", n, actual);
 310             }
 311         });
 312     }
 313 
 314     private static void squareRootLong() {
 315         LongStream longs = random.longs(SIZE, (long)Integer.MAX_VALUE + 1L,
 316             Long.MAX_VALUE);
 317         longs.forEach(i -> {
 318             BigInteger n = BigInteger.valueOf(i);
 319             BigInteger n2 = n.pow(2);
 320 
 321             // square root of n^2 -> n
 322             BigInteger actual = n2.sqrt();
 323             if (actual.compareTo(n) != 0) {
 324                 fail("sqrt(long)", n, actual);
 325             }
 326 
 327             // square root of n^2 + 1 -> n
 328             BigInteger n2up = n2.add(BigInteger.ONE);
 329             actual = n2up.sqrt();
 330             if (actual.compareTo(n) != 0) {
 331                 fail("sqrt(long)", n, actual);
 332             }
 333 
 334             // square root of (n + 1)^2 - 1 -> n
 335             BigInteger up = n.add(BigInteger.ONE).pow(2).subtract(BigInteger.ONE);
 336             actual = up.sqrt();
 337             if (actual.compareTo(n) != 0) {
 338                 fail("sqrt(long)", n, actual);
 339             }
 340         });
 341     }
 342 
 343     private static void squareRootDouble() {
 344         DoubleStream doubles = random.doubles(SIZE,
 345                 (double)Long.MAX_VALUE + 1.0, Math.sqrt(Double.MAX_VALUE));
 346         doubles.forEach(i -> {
 347             BigInteger n = BigDecimal.valueOf(i).toBigInteger();
 348             BigInteger n2 = n.pow(2);
 349 
 350             // square root of n^2 -> n
 351             BigInteger actual = n2.sqrt();
 352             if (actual.compareTo(n) != 0) {
 353                 fail("sqrt(double)", n, actual);
 354             }
 355 
 356             // square root of n^2 + 1 -> n
 357             BigInteger n2up = n2.add(BigInteger.ONE);
 358             actual = n2up.sqrt();
 359             if (actual.compareTo(n) != 0) {
 360                 fail("sqrt(double)", n, actual);
 361             }
 362 
 363             // square root of (n + 1)^2 - 1 -> n
 364             BigInteger up = n.add(BigInteger.ONE).pow(2).subtract(BigInteger.ONE);
 365             actual = up.sqrt();
 366             if (actual.compareTo(n) != 0) {
 367                 fail("sqrt(double)", n, actual);
 368             }
 369         });
 370     }
 371 
 372     public static void squareRoot() {
 373         squareRootSmall();
 374         squareRootInt();
 375         squareRootLong();
 376         squareRootDouble();
 377     }
 378 
 379     public static void squareRootAndRemainder() {
 380         IntStream bits = random.ints(SIZE, 3, Short.MAX_VALUE);
 381         bits.forEach(i -> {
 382             BigInteger n = new BigInteger(i, random);
 383             BigInteger n2 = n.pow(2);
 384 
 385             // square root of n^2 -> n
 386             BigInteger[] actual = n2.sqrtAndRemainder();
 387             if (actual[0].compareTo(n) != 0) {
 388                 fail("sqrtAndRemainder()[0]", n, actual[0]);
 389             }
 390             if (actual[1].compareTo(BigInteger.ZERO) != 0) {
 391                 fail("sqrtAndRemainder()[1]", BigInteger.ZERO, actual[1]);
 392             }
 393 
 394             // square root of n^2 + 1 -> n
 395             BigInteger n2up = n2.add(BigInteger.ONE);
 396             actual = n2up.sqrtAndRemainder();
 397             if (actual[0].compareTo(n) != 0) {
 398                 fail("sqrtAndRemainder()[0]", n, actual[0]);
 399             }
 400             if (actual[1].compareTo(BigInteger.ONE) != 0) {
 401                 fail("sqrtAndRemainder()[1]", BigInteger.ONE, actual[1]);
 402             }
 403 
 404             // square root of (n + 1)^2 - 1 -> n
 405             BigInteger up = n.add(BigInteger.ONE).pow(2).subtract(BigInteger.ONE);
 406             actual = up.sqrtAndRemainder();
 407             if (actual[0].compareTo(n) != 0) {
 408                 fail("sqrt(int)", n, actual[0]);
 409             }
 410             BigInteger r = up.subtract(n2);
 411             if (actual[1].compareTo(r) != 0) {
 412                 fail("sqrtAndRemainder()[1]", r, actual[1]);
 413             }
 414         });
 415     }
 416 
 417     public static void arithmetic(int order) {
 418         int failCount = 0;
 419 
 420         for (int i=0; i<SIZE; i++) {
 421             BigInteger x = fetchNumber(order);
 422             while(x.compareTo(BigInteger.ZERO) != 1)
 423                 x = fetchNumber(order);
 424             BigInteger y = fetchNumber(order/2);
 425             while(x.compareTo(y) == -1)
 426                 y = fetchNumber(order/2);
 427             if (y.equals(BigInteger.ZERO))
 428                 y = y.add(BigInteger.ONE);
 429 
 430             // Test identity ((x/y))*y + x%y - x == 0
 431             // using separate divide() and remainder()
 432             BigInteger baz = x.divide(y);
 433             baz = baz.multiply(y);
 434             baz = baz.add(x.remainder(y));
 435             baz = baz.subtract(x);
 436             if (!baz.equals(BigInteger.ZERO))


1255 
1256         prime();
1257         nextProbablePrime();
1258 
1259         arithmetic(order1);   // small numbers
1260         arithmetic(order3);   // Karatsuba range
1261         arithmetic(order4);   // Toom-Cook / Burnikel-Ziegler range
1262 
1263         divideAndRemainder(order1);   // small numbers
1264         divideAndRemainder(order3);   // Karatsuba range
1265         divideAndRemainder(order4);   // Toom-Cook / Burnikel-Ziegler range
1266 
1267         pow(order1);
1268         pow(order3);
1269         pow(order4);
1270 
1271         square(ORDER_MEDIUM);
1272         square(ORDER_KARATSUBA_SQUARE);
1273         square(ORDER_TOOM_COOK_SQUARE);
1274 
1275         squareRoot();
1276         squareRootAndRemainder();
1277 
1278         bitCount();
1279         bitLength();
1280         bitOps(order1);
1281         bitwise(order1);
1282 
1283         shift(order1);
1284 
1285         byteArrayConv(order1);
1286 
1287         modInv(order1);   // small numbers
1288         modInv(order3);   // Karatsuba range
1289         modInv(order4);   // Toom-Cook / Burnikel-Ziegler range
1290 
1291         modExp(order1, order2);
1292         modExp2(order1);
1293 
1294         stringConv();
1295         serialize();
1296 
1297         multiplyLarge();