Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/misc/FloatingDecimal/TestFDBigInteger.java
38838 views
/*1* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.math.BigInteger;24import java.util.Random;25import sun.misc.FDBigInteger;2627/**28* @test29* @bug 703215430* @summary unit testys of sun.misc.FDBigInteger31* @author Dmitry Nadezhin32*/33public class TestFDBigInteger {3435private static final int MAX_P5 = 413;36private static final int MAX_P2 = 65;37private static final long LONG_SIGN_MASK = (1L << 63);38private static final BigInteger FIVE = BigInteger.valueOf(5);39private static final FDBigInteger MUTABLE_ZERO = FDBigInteger.valueOfPow52(0, 0).leftInplaceSub(FDBigInteger.valueOfPow52(0, 0));40private static final FDBigInteger IMMUTABLE_ZERO = FDBigInteger.valueOfPow52(0, 0).leftInplaceSub(FDBigInteger.valueOfPow52(0, 0));41private static final FDBigInteger IMMUTABLE_MILLION = genMillion1();42private static final FDBigInteger IMMUTABLE_BILLION = genBillion1();43private static final FDBigInteger IMMUTABLE_TEN18 = genTen18();4445static {46IMMUTABLE_ZERO.makeImmutable();47IMMUTABLE_MILLION.makeImmutable();48IMMUTABLE_BILLION.makeImmutable();49IMMUTABLE_TEN18.makeImmutable();50}5152private static FDBigInteger mutable(String hex, int offset) {53char[] chars = new BigInteger(hex, 16).toString().toCharArray();54return new FDBigInteger(0, chars, 0, chars.length).multByPow52(0, offset * 32);55}5657private static FDBigInteger immutable(String hex, int offset) {58FDBigInteger fd = mutable(hex, offset);59fd.makeImmutable();60return fd;61}6263private static BigInteger biPow52(int p5, int p2) {64return FIVE.pow(p5).shiftLeft(p2);65}6667// data.length == 1, nWords == 1, offset == 068private static FDBigInteger genMillion1() {69return FDBigInteger.valueOfPow52(6, 0).leftShift(6);70}7172// data.length == 2, nWords == 1, offset == 073private static FDBigInteger genMillion2() {74return FDBigInteger.valueOfMulPow52(1000000L, 0, 0);75}7677// data.length == 1, nWords == 1, offset == 078private static FDBigInteger genBillion1() {79return FDBigInteger.valueOfPow52(9, 0).leftShift(9);80}8182// data.length == 2, nWords == 2, offset == 083private static FDBigInteger genTen18() {84return FDBigInteger.valueOfPow52(18, 0).leftShift(18);85}8687private static void check(BigInteger expected, FDBigInteger actual, String message) throws Exception {88if (!expected.equals(actual.toBigInteger())) {89throw new Exception(message + " result " + actual.toHexString() + " expected " + expected.toString(16));90}91}9293private static void testValueOfPow52(int p5, int p2) throws Exception {94check(biPow52(p5, p2), FDBigInteger.valueOfPow52(p5, p2),95"valueOfPow52(" + p5 + "," + p2 + ")");96}9798private static void testValueOfPow52() throws Exception {99for (int p5 = 0; p5 <= MAX_P5; p5++) {100for (int p2 = 0; p2 <= MAX_P2; p2++) {101testValueOfPow52(p5, p2);102}103}104}105106private static void testValueOfMulPow52(long value, int p5, int p2) throws Exception {107BigInteger bi = BigInteger.valueOf(value & ~LONG_SIGN_MASK);108if (value < 0) {109bi = bi.setBit(63);110}111check(biPow52(p5, p2).multiply(bi), FDBigInteger.valueOfMulPow52(value, p5, p2),112"valueOfMulPow52(" + Long.toHexString(value) + "." + p5 + "," + p2 + ")");113}114115private static void testValueOfMulPow52(long value, int p5) throws Exception {116testValueOfMulPow52(value, p5, 0);117testValueOfMulPow52(value, p5, 1);118testValueOfMulPow52(value, p5, 30);119testValueOfMulPow52(value, p5, 31);120testValueOfMulPow52(value, p5, 33);121testValueOfMulPow52(value, p5, 63);122}123124private static void testValueOfMulPow52() throws Exception {125for (int p5 = 0; p5 <= MAX_P5; p5++) {126testValueOfMulPow52(0xFFFFFFFFL, p5);127testValueOfMulPow52(0x123456789AL, p5);128testValueOfMulPow52(0x7FFFFFFFFFFFFFFFL, p5);129testValueOfMulPow52(0xFFFFFFFFFFF54321L, p5);130}131}132133private static void testLeftShift(FDBigInteger t, int shift, boolean isImmutable) throws Exception {134BigInteger bt = t.toBigInteger();135FDBigInteger r = t.leftShift(shift);136if ((bt.signum() == 0 || shift == 0 || !isImmutable) && r != t) {137throw new Exception("leftShift doesn't reuse its argument");138}139if (isImmutable) {140check(bt, t, "leftShift corrupts its argument");141}142check(bt.shiftLeft(shift), r, "leftShift returns wrong result");143}144145private static void testLeftShift() throws Exception {146testLeftShift(IMMUTABLE_ZERO, 0, true);147testLeftShift(IMMUTABLE_ZERO, 10, true);148testLeftShift(MUTABLE_ZERO, 0, false);149testLeftShift(MUTABLE_ZERO, 10, false);150151testLeftShift(IMMUTABLE_MILLION, 0, true);152testLeftShift(IMMUTABLE_MILLION, 1, true);153testLeftShift(IMMUTABLE_MILLION, 12, true);154testLeftShift(IMMUTABLE_MILLION, 13, true);155testLeftShift(IMMUTABLE_MILLION, 32, true);156testLeftShift(IMMUTABLE_MILLION, 33, true);157testLeftShift(IMMUTABLE_MILLION, 44, true);158testLeftShift(IMMUTABLE_MILLION, 45, true);159160testLeftShift(genMillion1(), 0, false);161testLeftShift(genMillion1(), 1, false);162testLeftShift(genMillion1(), 12, false);163testLeftShift(genMillion1(), 13, false);164testLeftShift(genMillion1(), 25, false);165testLeftShift(genMillion1(), 26, false);166testLeftShift(genMillion1(), 32, false);167testLeftShift(genMillion1(), 33, false);168testLeftShift(genMillion1(), 44, false);169testLeftShift(genMillion1(), 45, false);170171testLeftShift(genMillion2(), 0, false);172testLeftShift(genMillion2(), 1, false);173testLeftShift(genMillion2(), 12, false);174testLeftShift(genMillion2(), 13, false);175testLeftShift(genMillion2(), 25, false);176testLeftShift(genMillion2(), 26, false);177testLeftShift(genMillion2(), 32, false);178testLeftShift(genMillion2(), 33, false);179testLeftShift(genMillion2(), 44, false);180testLeftShift(genMillion2(), 45, false);181}182183private static void testQuoRemIteration(FDBigInteger t, FDBigInteger s) throws Exception {184BigInteger bt = t.toBigInteger();185BigInteger bs = s.toBigInteger();186int q = t.quoRemIteration(s);187BigInteger[] qr = bt.divideAndRemainder(bs);188if (!BigInteger.valueOf(q).equals(qr[0])) {189throw new Exception("quoRemIteration returns incorrect quo");190}191check(qr[1].multiply(BigInteger.TEN), t, "quoRemIteration returns incorrect rem");192}193194private static void testQuoRemIteration() throws Exception {195// IMMUTABLE_TEN18 == 0de0b6b3a7640000196// q = 0197testQuoRemIteration(mutable("00000001", 0), IMMUTABLE_TEN18);198testQuoRemIteration(mutable("00000001", 1), IMMUTABLE_TEN18);199testQuoRemIteration(mutable("0de0b6b2", 1), IMMUTABLE_TEN18);200// q = 1 -> q = 0201testQuoRemIteration(mutable("0de0b6b3", 1), IMMUTABLE_TEN18);202testQuoRemIteration(mutable("0de0b6b3a763FFFF", 0), IMMUTABLE_TEN18);203// q = 1204testQuoRemIteration(mutable("0de0b6b3a7640000", 0), IMMUTABLE_TEN18);205testQuoRemIteration(mutable("0de0b6b3FFFFFFFF", 0), IMMUTABLE_TEN18);206testQuoRemIteration(mutable("8ac72304", 1), IMMUTABLE_TEN18);207testQuoRemIteration(mutable("0de0b6b400000000", 0), IMMUTABLE_TEN18);208testQuoRemIteration(mutable("8ac72305", 1), IMMUTABLE_TEN18);209// q = 18210testQuoRemIteration(mutable("FFFFFFFF", 1), IMMUTABLE_TEN18);211}212213private static void testCmp(FDBigInteger t, FDBigInteger o) throws Exception {214BigInteger bt = t.toBigInteger();215BigInteger bo = o.toBigInteger();216int cmp = t.cmp(o);217int bcmp = bt.compareTo(bo);218if (bcmp != cmp) {219throw new Exception("cmp returns " + cmp + " expected " + bcmp);220}221check(bt, t, "cmp corrupts this");222check(bo, o, "cmp corrupts other");223if (o.cmp(t) != -cmp) {224throw new Exception("asymmetrical cmp");225}226check(bt, t, "cmp corrupts this");227check(bo, o, "cmp corrupts other");228}229230private static void testCmp() throws Exception {231testCmp(mutable("FFFFFFFF", 0), mutable("100000000", 0));232testCmp(mutable("FFFFFFFF", 0), mutable("1", 1));233testCmp(mutable("5", 0), mutable("6", 0));234testCmp(mutable("5", 0), mutable("5", 0));235testCmp(mutable("5000000001", 0), mutable("500000001", 0));236testCmp(mutable("5000000001", 0), mutable("6", 1));237testCmp(mutable("5000000001", 0), mutable("5", 1));238testCmp(mutable("5000000000", 0), mutable("5", 1));239}240241private static void testCmpPow52(FDBigInteger t, int p5, int p2) throws Exception {242FDBigInteger o = FDBigInteger.valueOfPow52(p5, p2);243BigInteger bt = t.toBigInteger();244BigInteger bo = biPow52(p5, p2);245int cmp = t.cmp(o);246int bcmp = bt.compareTo(bo);247if (bcmp != cmp) {248throw new Exception("cmpPow52 returns " + cmp + " expected " + bcmp);249}250check(bt, t, "cmpPow52 corrupts this");251check(bo, o, "cmpPow5 corrupts other");252}253254private static void testCmpPow52() throws Exception {255testCmpPow52(mutable("00000002", 1), 0, 31);256testCmpPow52(mutable("00000002", 1), 0, 32);257testCmpPow52(mutable("00000002", 1), 0, 33);258testCmpPow52(mutable("00000002", 1), 0, 34);259testCmpPow52(mutable("00000002", 1), 0, 64);260testCmpPow52(mutable("00000003", 1), 0, 32);261testCmpPow52(mutable("00000003", 1), 0, 33);262testCmpPow52(mutable("00000003", 1), 0, 34);263}264265private static void testAddAndCmp(FDBigInteger t, FDBigInteger x, FDBigInteger y) throws Exception {266BigInteger bt = t.toBigInteger();267BigInteger bx = x.toBigInteger();268BigInteger by = y.toBigInteger();269int cmp = t.addAndCmp(x, y);270int bcmp = bt.compareTo(bx.add(by));271if (bcmp != cmp) {272throw new Exception("addAndCmp returns " + cmp + " expected " + bcmp);273}274check(bt, t, "addAndCmp corrupts this");275check(bx, x, "addAndCmp corrupts x");276check(by, y, "addAndCmp corrupts y");277}278279private static void testAddAndCmp() throws Exception {280testAddAndCmp(MUTABLE_ZERO, MUTABLE_ZERO, MUTABLE_ZERO);281testAddAndCmp(mutable("00000001", 0), MUTABLE_ZERO, MUTABLE_ZERO);282testAddAndCmp(mutable("00000001", 0), mutable("00000001", 0), MUTABLE_ZERO);283testAddAndCmp(mutable("00000001", 0), MUTABLE_ZERO, mutable("00000001", 0));284testAddAndCmp(mutable("00000001", 0), mutable("00000002", 0), MUTABLE_ZERO);285testAddAndCmp(mutable("00000001", 0), MUTABLE_ZERO, mutable("00000002", 0));286testAddAndCmp(mutable("00000001", 2), mutable("FFFFFFFF", 0), mutable("FFFFFFFF", 0));287testAddAndCmp(mutable("00000001", 0), mutable("00000001", 1), mutable("00000001", 0));288289testAddAndCmp(mutable("00000001", 2), mutable("0F0F0F0F80000000", 1), mutable("F0F0F0F080000000", 1));290testAddAndCmp(mutable("00000001", 2), mutable("0F0F0F0E80000000", 1), mutable("F0F0F0F080000000", 1));291292testAddAndCmp(mutable("00000002", 1), mutable("0000000180000000", 1), mutable("0000000280000000", 1));293testAddAndCmp(mutable("00000003", 1), mutable("0000000180000000", 1), mutable("0000000280000000", 1));294testAddAndCmp(mutable("00000004", 1), mutable("0000000180000000", 1), mutable("0000000280000000", 1));295testAddAndCmp(mutable("00000005", 1), mutable("0000000180000000", 1), mutable("0000000280000000", 1));296297testAddAndCmp(mutable("00000001", 2), mutable("8000000000000000", 0), mutable("8000000000000000", 0));298testAddAndCmp(mutable("00000001", 2), mutable("8000000000000000", 0), mutable("8000000000000001", 0));299testAddAndCmp(mutable("00000002", 2), mutable("8000000000000000", 0), mutable("8000000000000000", 0));300testAddAndCmp(mutable("00000003", 2), mutable("8000000000000000", 0), mutable("8000000000000000", 0));301}302303private static void testMultBy10(FDBigInteger t, boolean isImmutable) throws Exception {304BigInteger bt = t.toBigInteger();305FDBigInteger r = t.multBy10();306if ((bt.signum() == 0 || !isImmutable) && r != t) {307throw new Exception("multBy10 of doesn't reuse its argument");308}309if (isImmutable) {310check(bt, t, "multBy10 corrupts its argument");311}312check(bt.multiply(BigInteger.TEN), r, "multBy10 returns wrong result");313}314315private static void testMultBy10() throws Exception {316for (int p5 = 0; p5 <= MAX_P5; p5++) {317for (int p2 = 0; p2 <= MAX_P2; p2++) {318// This strange way of creating a value ensures that it is mutable.319FDBigInteger value = FDBigInteger.valueOfPow52(0, 0).multByPow52(p5, p2);320testMultBy10(value, false);321value.makeImmutable();322testMultBy10(value, true);323}324}325}326327private static void testMultByPow52(FDBigInteger t, int p5, int p2) throws Exception {328BigInteger bt = t.toBigInteger();329FDBigInteger r = t.multByPow52(p5, p2);330if (bt.signum() == 0 && r != t) {331throw new Exception("multByPow52 of doesn't reuse its argument");332}333check(bt.multiply(biPow52(p5, p2)), r, "multByPow52 returns wrong result");334}335336private static void testMultByPow52() throws Exception {337for (int p5 = 0; p5 <= MAX_P5; p5++) {338for (int p2 = 0; p2 <= MAX_P2; p2++) {339// This strange way of creating a value ensures that it is mutable.340FDBigInteger value = FDBigInteger.valueOfPow52(0, 0).multByPow52(p5, p2);341testMultByPow52(value, p5, p2);342}343}344}345346private static void testLeftInplaceSub(FDBigInteger left, FDBigInteger right, boolean isImmutable) throws Exception {347BigInteger biLeft = left.toBigInteger();348BigInteger biRight = right.toBigInteger();349FDBigInteger diff = left.leftInplaceSub(right);350if (!isImmutable && diff != left) {351throw new Exception("leftInplaceSub of doesn't reuse its argument");352}353if (isImmutable) {354check(biLeft, left, "leftInplaceSub corrupts its left immutable argument");355}356check(biRight, right, "leftInplaceSub corrupts its right argument");357check(biLeft.subtract(biRight), diff, "leftInplaceSub returns wrong result");358}359360private static void testLeftInplaceSub() throws Exception {361for (int p5 = 0; p5 <= MAX_P5; p5++) {362for (int p2 = 0; p2 <= MAX_P2; p2++) {363// for (int p5r = 0; p5r <= p5; p5r += 10) {364// for (int p2r = 0; p2r <= p2; p2r += 10) {365for (int p5r = 0; p5r <= p5; p5r++) {366for (int p2r = 0; p2r <= p2; p2r++) {367// This strange way of creating a value ensures that it is mutable.368FDBigInteger left = FDBigInteger.valueOfPow52(0, 0).multByPow52(p5, p2);369FDBigInteger right = FDBigInteger.valueOfPow52(0, 0).multByPow52(p5r, p2r);370testLeftInplaceSub(left, right, false);371left = FDBigInteger.valueOfPow52(0, 0).multByPow52(p5, p2);372left.makeImmutable();373testLeftInplaceSub(left, right, true);374}375}376}377}378}379380private static void testRightInplaceSub(FDBigInteger left, FDBigInteger right, boolean isImmutable) throws Exception {381BigInteger biLeft = left.toBigInteger();382BigInteger biRight = right.toBigInteger();383FDBigInteger diff = left.rightInplaceSub(right);384if (!isImmutable && diff != right) {385throw new Exception("rightInplaceSub of doesn't reuse its argument");386}387check(biLeft, left, "leftInplaceSub corrupts its left argument");388if (isImmutable) {389check(biRight, right, "leftInplaceSub corrupts its right immutable argument");390}391try {392check(biLeft.subtract(biRight), diff, "rightInplaceSub returns wrong result");393} catch (Exception e) {394System.out.println(biLeft+" - "+biRight+" = "+biLeft.subtract(biRight));395throw e;396}397}398399private static void testRightInplaceSub() throws Exception {400for (int p5 = 0; p5 <= MAX_P5; p5++) {401for (int p2 = 0; p2 <= MAX_P2; p2++) {402// for (int p5r = 0; p5r <= p5; p5r += 10) {403// for (int p2r = 0; p2r <= p2; p2r += 10) {404for (int p5r = 0; p5r <= p5; p5r++) {405for (int p2r = 0; p2r <= p2; p2r++) {406// This strange way of creating a value ensures that it is mutable.407FDBigInteger left = FDBigInteger.valueOfPow52(0, 0).multByPow52(p5, p2);408FDBigInteger right = FDBigInteger.valueOfPow52(0, 0).multByPow52(p5r, p2r);409testRightInplaceSub(left, right, false);410right = FDBigInteger.valueOfPow52(0, 0).multByPow52(p5r, p2r);411right.makeImmutable();412testRightInplaceSub(left, right, true);413}414}415}416}417}418419public static void main(String[] args) throws Exception {420testValueOfPow52();421testValueOfMulPow52();422testLeftShift();423testQuoRemIteration();424testCmp();425testCmpPow52();426testAddAndCmp();427// Uncomment the following for more comprehensize but slow testing.428// testLeftInplaceSub();429// testMultBy10();430// testMultByPow52();431// testRightInplaceSub();432}433}434435436