Path: blob/master/test/jdk/java/lang/Long/Unsigned.java
41149 views
/*1* Copyright (c) 2009, 2020, 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*/2223/*24* @test25* @bug 4504839 4215269 6322074 803081426* @summary Basic tests for unsigned operations27* @author Joseph D. Darcy28*/2930import java.math.*;3132public class Unsigned {33public static void main(String... args) {34int errors = 0;3536errors += testRoundtrip();37errors += testByteToUnsignedLong();38errors += testShortToUnsignedLong();39errors += testUnsignedCompare();40errors += testToStringUnsigned();41errors += testParseUnsignedLong();42errors += testDivideAndRemainder();4344if (errors > 0) {45throw new RuntimeException(errors + " errors found in unsigned operations.");46}47}4849private static final BigInteger TWO = BigInteger.valueOf(2L);5051private static int testRoundtrip() {52int errors = 0;5354long[] data = {-1L, 0L, 1L};5556for(long datum : data) {57if (Long.parseUnsignedLong(Long.toBinaryString(datum), 2) != datum) {58errors++;59System.err.println("Bad binary roundtrip conversion of " + datum);60}6162if (Long.parseUnsignedLong(Long.toOctalString(datum), 8) != datum) {63errors++;64System.err.println("Bad octal roundtrip conversion of " + datum);65}6667if (Long.parseUnsignedLong(Long.toHexString(datum), 16) != datum) {68errors++;69System.err.println("Bad hex roundtrip conversion of " + datum);70}71}72return errors;73}7475private static int testByteToUnsignedLong() {76int errors = 0;7778for(int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {79byte datum = (byte) i;80long ui = Byte.toUnsignedLong(datum);8182if ( (ui & (~0xffL)) != 0L ||83((byte)ui != datum )) {84errors++;85System.err.printf("Bad conversion of byte %d to unsigned long %d%n",86datum, ui);87}88}89return errors;90}9192private static int testShortToUnsignedLong() {93int errors = 0;9495for(int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; i++) {96short datum = (short) i;97long ui = Short.toUnsignedLong(datum);9899if ( (ui & (~0xffffL)) != 0L ||100((short)ui != datum )) {101errors++;102System.err.printf("Bad conversion of short %d to unsigned long %d%n",103datum, ui);104}105}106return errors;107}108private static int testUnsignedCompare() {109int errors = 0;110111long[] data = {1120L,1131L,1142L,1153L,1160x00000000_80000000L,1170x00000000_FFFFFFFFL,1180x00000001_00000000L,1190x80000000_00000000L,1200x80000000_00000001L,1210x80000000_00000002L,1220x80000000_00000003L,1230x80000000_80000000L,1240xFFFFFFFF_FFFFFFFEL,1250xFFFFFFFF_FFFFFFFFL,126};127128for(long i : data) {129for(long j : data) {130long libraryResult = Long.compareUnsigned(i, j);131long libraryResultRev = Long.compareUnsigned(j, i);132long localResult = compUnsigned(i, j);133134if (i == j) {135if (libraryResult != 0) {136errors++;137System.err.printf("Value 0x%x did not compare as " +138"an unsigned equal to itself; got %d%n",139i, libraryResult);140}141}142143if (Long.signum(libraryResult) != Long.signum(localResult)) {144errors++;145System.err.printf("Unsigned compare of 0x%x to 0x%x%n:" +146"\texpected sign of %d, got %d%n",147i, j, localResult, libraryResult);148}149150if (Long.signum(libraryResult) !=151-Long.signum(libraryResultRev)) {152errors++;153System.err.printf("signum(compareUnsigned(x, y)) != -signum(compareUnsigned(y,x))" +154" for \t0x%x and 0x%x, computed %d and %d%n",155i, j, libraryResult, libraryResultRev);156}157}158}159160return errors;161}162163private static int compUnsigned(long x, long y) {164BigInteger big_x = toUnsignedBigInt(x);165BigInteger big_y = toUnsignedBigInt(y);166167return big_x.compareTo(big_y);168}169170private static BigInteger toUnsignedBigInt(long x) {171if (x >= 0)172return BigInteger.valueOf(x);173else {174int upper = (int)(((long)x) >> 32);175int lower = (int) x;176177BigInteger bi = // (upper << 32) + lower178(BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).179add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));180181// System.out.printf("%n\t%d%n\t%s%n", x, bi.toString());182return bi;183}184}185186private static int testToStringUnsigned() {187int errors = 0;188189long[] data = {1900L,1911L,1922L,1933L,19499999L,195100000L,196999999L,197100000L,198999999999L,1991000000000L,2000x1234_5678L,2010x8000_0000L,2020x8000_0001L,2030x8000_0002L,2040x8000_0003L,2050x8765_4321L,2060xFFFF_FFFEL,2070xFFFF_FFFFL,208209// Long-range values210999_999_999_999L,2111_000_000_000_000L,212213999_999_999_999_999_999L,2141_000_000_000_000_000_000L,2152160xFFFF_FFFF_FFFF_FFFEL,2170xFFFF_FFFF_FFFF_FFFFL,218};219220for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {221for(long datum : data) {222String result1 = Long.toUnsignedString(datum, radix);223String result2 = toUnsignedBigInt(datum).toString(radix);224225if (!result1.equals(result2)) {226errors++;227System.err.printf("Unexpected string difference converting 0x%x:" +228"\t%s %s%n",229datum, result1, result2);230}231232if (radix == 10) {233String result3 = Long.toUnsignedString(datum);234if (!result2.equals(result3)) {235errors++;236System.err.printf("Unexpected string difference converting 0x%x:" +237"\t%s %s%n",238datum, result3, result2);239}240}241242long parseResult = Long.parseUnsignedLong(result1, radix);243244if (parseResult != datum) {245errors++;246System.err.printf("Bad roundtrip conversion of %d in base %d" +247"\tconverting back ''%s'' resulted in %d%n",248datum, radix, result1, parseResult);249}250}251}252253return errors;254}255256private static int testParseUnsignedLong() {257int errors = 0;258long maxUnsignedInt = Integer.toUnsignedLong(0xffff_ffff);259260// Values include those between signed Long.MAX_VALUE and261// unsignted Long MAX_VALUE.262BigInteger[] inRange = {263BigInteger.valueOf(0L),264BigInteger.valueOf(1L),265BigInteger.valueOf(10L),266BigInteger.valueOf(2147483646L), // Integer.MAX_VALUE - 1267BigInteger.valueOf(2147483647L), // Integer.MAX_VALUE268BigInteger.valueOf(2147483648L), // Integer.MAX_VALUE + 1269270BigInteger.valueOf(maxUnsignedInt - 1L),271BigInteger.valueOf(maxUnsignedInt),272273BigInteger.valueOf(Long.MAX_VALUE - 1L),274BigInteger.valueOf(Long.MAX_VALUE),275BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE),276277TWO.pow(64).subtract(BigInteger.ONE)278};279280for(BigInteger value : inRange) {281for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {282String bigString = value.toString(radix);283long longResult = Long.parseUnsignedLong(bigString, radix);284285if (!toUnsignedBigInt(longResult).equals(value)) {286errors++;287System.err.printf("Bad roundtrip conversion of %d in base %d" +288"\tconverting back ''%s'' resulted in %d%n",289value, radix, bigString, longResult);290}291292// test offset based parse method293longResult = Long.parseUnsignedLong("prefix" + bigString + "suffix", "prefix".length(),294"prefix".length() + bigString.length(), radix);295296if (!toUnsignedBigInt(longResult).equals(value)) {297errors++;298System.err.printf("Bad roundtrip conversion of %d in base %d" +299"\tconverting back ''%s'' resulted in %d%n",300value, radix, bigString, longResult);301}302}303}304305String[] outOfRange = {306null,307"",308"-1",309TWO.pow(64).toString(),310};311312for(String s : outOfRange) {313try {314long result = Long.parseUnsignedLong(s);315errors++; // Should not reach here316System.err.printf("Unexpected got %d from an unsigned conversion of %s",317result, s);318} catch(NumberFormatException nfe) {319; // Correct result320}321}322323// test case known at one time to fail324errors += testUnsignedOverflow("1234567890abcdef1", 16, true);325326// largest value with guard = 91 = 13*7; radix = 13327errors += testUnsignedOverflow("196a78a44c3bba320c", 13, false);328329// smallest value with guard = 92 = 23*2*2; radix = 23330errors += testUnsignedOverflow("137060c6g1c1dg0", 23, false);331332// guard in [92,98]: no overflow333334// one less than smallest guard value to overflow: guard = 99 = 11*3*3, radix = 33335errors += testUnsignedOverflow("b1w8p7j5q9r6f", 33, false);336337// smallest guard value to overflow: guard = 99 = 11*3*3, radix = 33338errors += testUnsignedOverflow("b1w8p7j5q9r6g", 33, true);339340// test overflow of overflow341BigInteger maxUnsignedLong =342BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE);343for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {344BigInteger quotient = maxUnsignedLong.divide(BigInteger.valueOf(radix));345for (int addend = 2; addend <= radix; addend++) {346BigInteger b = quotient.multiply(BigInteger.valueOf(radix + addend));347errors += testUnsignedOverflow(b.toString(radix), radix, b.compareTo(maxUnsignedLong) > 0);348}349}350351return errors;352}353354// test for missing or unexpected unsigned overflow exception355private static int testUnsignedOverflow(String s, int radix, boolean exception) {356int errors = 0;357long result;358try {359result = Long.parseUnsignedLong(s, radix);360if (exception) {361System.err.printf("Unexpected result %d for Long.parseUnsignedLong(%s,%d)\n",362result, s, radix);363errors++;364}365} catch (NumberFormatException nfe) {366if (!exception) {367System.err.printf("Unexpected exception %s for Long.parseUnsignedLong(%s,%d)\n",368nfe.toString(), s, radix);369errors++;370}371}372return errors;373}374375private static int testDivideAndRemainder() {376int errors = 0;377long TWO_31 = 1L << Integer.SIZE - 1;378long TWO_32 = 1L << Integer.SIZE;379long TWO_33 = 1L << Integer.SIZE + 1;380BigInteger NINETEEN = BigInteger.valueOf(19L);381BigInteger TWO_63 = BigInteger.ONE.shiftLeft(Long.SIZE - 1);382BigInteger TWO_64 = BigInteger.ONE.shiftLeft(Long.SIZE);383384BigInteger[] inRange = {385BigInteger.ZERO,386BigInteger.ONE,387BigInteger.TEN,388NINETEEN,389390BigInteger.valueOf(TWO_31 - 19L),391BigInteger.valueOf(TWO_31 - 10L),392BigInteger.valueOf(TWO_31 - 1L),393BigInteger.valueOf(TWO_31),394BigInteger.valueOf(TWO_31 + 1L),395BigInteger.valueOf(TWO_31 + 10L),396BigInteger.valueOf(TWO_31 + 19L),397398BigInteger.valueOf(TWO_32 - 19L),399BigInteger.valueOf(TWO_32 - 10L),400BigInteger.valueOf(TWO_32 - 1L),401BigInteger.valueOf(TWO_32),402BigInteger.valueOf(TWO_32 + 1L),403BigInteger.valueOf(TWO_32 + 10L),404BigInteger.valueOf(TWO_32 - 19L),405406BigInteger.valueOf(TWO_33 - 19L),407BigInteger.valueOf(TWO_33 - 10L),408BigInteger.valueOf(TWO_33 - 1L),409BigInteger.valueOf(TWO_33),410BigInteger.valueOf(TWO_33 + 1L),411BigInteger.valueOf(TWO_33 + 10L),412BigInteger.valueOf(TWO_33 + 19L),413414TWO_63.subtract(NINETEEN),415TWO_63.subtract(BigInteger.TEN),416TWO_63.subtract(BigInteger.ONE),417TWO_63,418TWO_63.add(BigInteger.ONE),419TWO_63.add(BigInteger.TEN),420TWO_63.add(NINETEEN),421422TWO_64.subtract(NINETEEN),423TWO_64.subtract(BigInteger.TEN),424TWO_64.subtract(BigInteger.ONE),425};426427for(BigInteger dividend : inRange) {428for(BigInteger divisor : inRange) {429long quotient;430BigInteger longQuotient;431432long remainder;433BigInteger longRemainder;434435if (divisor.equals(BigInteger.ZERO)) {436try {437quotient = Long.divideUnsigned(dividend.longValue(), divisor.longValue());438errors++;439} catch(ArithmeticException ea) {440; // Expected441}442443try {444remainder = Long.remainderUnsigned(dividend.longValue(), divisor.longValue());445errors++;446} catch(ArithmeticException ea) {447; // Expected448}449} else {450quotient = Long.divideUnsigned(dividend.longValue(), divisor.longValue());451longQuotient = dividend.divide(divisor);452453if (quotient != longQuotient.longValue()) {454errors++;455System.err.printf("Unexpected unsigned divide result %s on %s/%s%n",456Long.toUnsignedString(quotient),457Long.toUnsignedString(dividend.longValue()),458Long.toUnsignedString(divisor.longValue()));459}460461remainder = Long.remainderUnsigned(dividend.longValue(), divisor.longValue());462longRemainder = dividend.remainder(divisor);463464if (remainder != longRemainder.longValue()) {465errors++;466System.err.printf("Unexpected unsigned remainder result %s on %s%%%s%n",467Long.toUnsignedString(remainder),468Long.toUnsignedString(dividend.longValue()),469Long.toUnsignedString(divisor.longValue()));470}471}472}473}474475return errors;476}477}478479480