11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in compliance with the License. You may obtain a copy of the License at
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software distributed under the
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * express or implied. See the License for the specific language governing permissions and
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.primitives;
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Random;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestCase;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.NullPointerTester;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tests for UnsignedInts
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class UnsignedIntsTest extends TestCase {
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final long[] UNSIGNED_INTS = {
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0L,
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      1L,
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      2L,
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      3L,
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x12345678L,
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x5a4316b8L,
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0x6cf78a4bL,
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0xff1a618bL,
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0xfffffffdL,
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0xfffffffeL,
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      0xffffffffL};
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testToLong() {
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : UNSIGNED_INTS) {
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(a, UnsignedInts.toLong((int) a));
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCompare() {
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : UNSIGNED_INTS) {
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long b : UNSIGNED_INTS) {
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        int cmpAsLongs = Longs.compare(a, b);
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        int cmpAsUInt = UnsignedInts.compare((int) a, (int) b);
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(Integer.signum(cmpAsLongs), Integer.signum(cmpAsUInt));
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testDivide() {
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : UNSIGNED_INTS) {
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long b : UNSIGNED_INTS) {
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals((int) (a / b), UnsignedInts.divide((int) a, (int) b));
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertFalse(b == 0);
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException e) {
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(0, b);
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testRemainder() {
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : UNSIGNED_INTS) {
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long b : UNSIGNED_INTS) {
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals((int) (a % b), UnsignedInts.remainder((int) a, (int) b));
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertFalse(b == 0);
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } catch (ArithmeticException e) {
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          assertEquals(0, b);
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Too slow in GWT (~3min fully optimized)")
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testDivideRemainderEuclideanProperty() {
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Use a seed so that the test is deterministic:
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Random r = new Random(0L);
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0; i < 1000000; i++) {
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int dividend = r.nextInt();
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int divisor = r.nextInt();
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Test that the Euclidean property is preserved:
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(dividend
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          - (divisor * UnsignedInts.divide(dividend, divisor) + UnsignedInts.remainder(dividend,
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              divisor)) == 0);
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testParseInt() {
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (long a : UNSIGNED_INTS) {
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a)));
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NumberFormatException e) {
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail(e.getMessage());
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      UnsignedInts.parseUnsignedInt(Long.toString(1L << 32));
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Expected NumberFormatException");
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NumberFormatException expected) {}
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testParseLongWithRadix() throws NumberFormatException {
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : UNSIGNED_INTS) {
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a, radix), radix));
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // loops through all legal radix values.
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // tests can successfully parse a number string with this radix.
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      String maxAsString = Long.toString((1L << 32) - 1, radix);
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals(-1, UnsignedInts.parseUnsignedInt(maxAsString, radix));
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // tests that we get exception whre an overflow would occur.
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        long overflow = 1L << 32;
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        String overflowAsString = Long.toString(overflow, radix);
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        UnsignedInts.parseUnsignedInt(overflowAsString, radix);
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail();
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (NumberFormatException expected) {}
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testParseLongThrowsExceptionForInvalidRadix() {
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // inclusive.
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      UnsignedInts.parseUnsignedInt("0", Character.MIN_RADIX - 1);
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NumberFormatException expected) {}
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      UnsignedInts.parseUnsignedInt("0", Character.MAX_RADIX + 1);
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NumberFormatException expected) {}
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // The radix is used as an array index, so try a negative value.
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      UnsignedInts.parseUnsignedInt("0", -1);
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NumberFormatException expected) {}
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testToString() {
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int[] bases = {2, 5, 7, 8, 10, 16};
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (long a : UNSIGNED_INTS) {
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int base : bases) {
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertEquals(UnsignedInts.toString((int) a, base), Long.toString(a, base));
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("NullPointerTester")
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testNulls() throws Exception {
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    NullPointerTester tester = new NullPointerTester();
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester.setDefault(int[].class, new int[0]);
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester.testAllPublicStaticMethods(UnsignedInts.class);
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
175