Home | History | Annotate | Download | only in primitives
      1 /*
      2  * Copyright (C) 2011 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
      5  * in compliance with the License. You may obtain a copy of the License at
      6  *
      7  * http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software distributed under the
     10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     11  * express or implied. See the License for the specific language governing permissions and
     12  * limitations under the License.
     13  */
     14 
     15 package com.google.common.primitives;
     16 
     17 import static java.math.BigInteger.ONE;
     18 
     19 import java.math.BigInteger;
     20 import java.util.Random;
     21 
     22 import junit.framework.TestCase;
     23 
     24 import com.google.common.annotations.GwtCompatible;
     25 import com.google.common.annotations.GwtIncompatible;
     26 import com.google.common.testing.NullPointerTester;
     27 
     28 /**
     29  * Tests for UnsignedLongs
     30  *
     31  * @author Brian Milch
     32  * @author Louis Wasserman
     33  */
     34 @GwtCompatible(emulated = true)
     35 public class UnsignedLongsTest extends TestCase {
     36 
     37   public void testCompare() {
     38     // max value
     39     assertTrue((UnsignedLongs.compare(0, 0xffffffffffffffffL) < 0));
     40     assertTrue((UnsignedLongs.compare(0xffffffffffffffffL, 0) > 0));
     41 
     42     // both with high bit set
     43     assertTrue((UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xffffffffffffffffL) < 0));
     44     assertTrue((UnsignedLongs.compare(0xffffffffffffffffL, 0xff1a618b7f65ea12L) > 0));
     45 
     46     // one with high bit set
     47     assertTrue((UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0xff1a618b7f65ea12L) < 0));
     48     assertTrue((UnsignedLongs.compare(0xff1a618b7f65ea12L, 0x5a4316b8c153ac4dL) > 0));
     49 
     50     // neither with high bit set
     51     assertTrue((UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0x6cf78a4b139a4e2aL) < 0));
     52     assertTrue((UnsignedLongs.compare(0x6cf78a4b139a4e2aL, 0x5a4316b8c153ac4dL) > 0));
     53 
     54     // same value
     55     assertTrue((UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xff1a618b7f65ea12L) == 0));
     56   }
     57 
     58   public void testDivide() {
     59     assertEquals(2, UnsignedLongs.divide(14, 5));
     60     assertEquals(0, UnsignedLongs.divide(0, 50));
     61     assertEquals(1, UnsignedLongs.divide(0xfffffffffffffffeL, 0xfffffffffffffffdL));
     62     assertEquals(0, UnsignedLongs.divide(0xfffffffffffffffdL, 0xfffffffffffffffeL));
     63     assertEquals(281479271743488L, UnsignedLongs.divide(0xfffffffffffffffeL, 65535));
     64     assertEquals(0x7fffffffffffffffL, UnsignedLongs.divide(0xfffffffffffffffeL, 2));
     65     assertEquals(3689348814741910322L, UnsignedLongs.divide(0xfffffffffffffffeL, 5));
     66   }
     67 
     68   public void testRemainder() {
     69     assertEquals(4, UnsignedLongs.remainder(14, 5));
     70     assertEquals(0, UnsignedLongs.remainder(0, 50));
     71     assertEquals(1, UnsignedLongs.remainder(0xfffffffffffffffeL, 0xfffffffffffffffdL));
     72     assertEquals(0xfffffffffffffffdL,
     73         UnsignedLongs.remainder(0xfffffffffffffffdL, 0xfffffffffffffffeL));
     74     assertEquals(65534L, UnsignedLongs.remainder(0xfffffffffffffffeL, 65535));
     75     assertEquals(0, UnsignedLongs.remainder(0xfffffffffffffffeL, 2));
     76     assertEquals(4, UnsignedLongs.remainder(0xfffffffffffffffeL, 5));
     77   }
     78 
     79   @GwtIncompatible("Too slow in GWT (~3min fully optimized)")
     80   public void testDivideRemainderEuclideanProperty() {
     81     // Use a seed so that the test is deterministic:
     82     Random r = new Random(0L);
     83     for (int i = 0; i < 1000000; i++) {
     84       long dividend = r.nextLong();
     85       long divisor = r.nextLong();
     86       // Test that the Euclidean property is preserved:
     87       assertTrue(dividend - (divisor * UnsignedLongs.divide(dividend, divisor)
     88           + UnsignedLongs.remainder(dividend, divisor)) == 0);
     89     }
     90   }
     91 
     92   public void testParseLong() {
     93     try {
     94       assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("18446744073709551615"));
     95       assertEquals(0x7fffffffffffffffL, UnsignedLongs.parseUnsignedLong("9223372036854775807"));
     96       assertEquals(0xff1a618b7f65ea12L, UnsignedLongs.parseUnsignedLong("18382112080831834642"));
     97       assertEquals(0x5a4316b8c153ac4dL, UnsignedLongs.parseUnsignedLong("6504067269626408013"));
     98       assertEquals(0x6cf78a4b139a4e2aL, UnsignedLongs.parseUnsignedLong("7851896530399809066"));
     99     } catch (NumberFormatException e) {
    100       fail(e.getMessage());
    101     }
    102 
    103     boolean overflowCaught = false;
    104     try {
    105       // One more than maximum value
    106       UnsignedLongs.parseUnsignedLong("18446744073709551616");
    107     } catch (NumberFormatException e) {
    108       overflowCaught = true;
    109     }
    110     assertTrue(overflowCaught);
    111   }
    112 
    113   public void testParseLongWithRadix() throws NumberFormatException {
    114     assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("ffffffffffffffff", 16));
    115     assertEquals(0x1234567890abcdefL, UnsignedLongs.parseUnsignedLong("1234567890abcdef", 16));
    116 
    117     BigInteger max = BigInteger.ZERO.setBit(64).subtract(ONE);
    118     // loops through all legal radix values.
    119     for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
    120       // tests can successfully parse a number string with this radix.
    121       String maxAsString = max.toString(radix);
    122       assertEquals(max.longValue(), UnsignedLongs.parseUnsignedLong(maxAsString, radix));
    123 
    124       try {
    125         // tests that we get exception whre an overflow would occur.
    126         BigInteger overflow = max.add(ONE);
    127         String overflowAsString = overflow.toString(radix);
    128         UnsignedLongs.parseUnsignedLong(overflowAsString, radix);
    129         fail();
    130       } catch (NumberFormatException nfe) {
    131         // expected
    132       }
    133     }
    134   }
    135 
    136   public void testParseLongThrowsExceptionForInvalidRadix() {
    137     // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
    138     // inclusive.
    139     try {
    140       UnsignedLongs.parseUnsignedLong("0", Character.MIN_RADIX - 1);
    141       fail();
    142     } catch (NumberFormatException nfe) {
    143       // expected
    144     }
    145 
    146     try {
    147       UnsignedLongs.parseUnsignedLong("0", Character.MAX_RADIX + 1);
    148       fail();
    149     } catch (NumberFormatException nfe) {
    150       // expected
    151     }
    152 
    153     // The radix is used as an array index, so try a negative value.
    154     try {
    155       UnsignedLongs.parseUnsignedLong("0", -1);
    156       fail();
    157     } catch (NumberFormatException nfe) {
    158       // expected
    159     }
    160   }
    161 
    162   public void testToString() {
    163     String[] tests = {
    164         "ffffffffffffffff",
    165         "7fffffffffffffff",
    166         "ff1a618b7f65ea12",
    167         "5a4316b8c153ac4d",
    168         "6cf78a4b139a4e2a"};
    169     int[] bases = {2, 5, 7, 8, 10, 16};
    170     for (int base : bases) {
    171       for (String x : tests) {
    172         BigInteger xValue = new BigInteger(x, 16);
    173         long xLong = xValue.longValue(); // signed
    174         assertEquals(xValue.toString(base), UnsignedLongs.toString(xLong, base));
    175       }
    176     }
    177   }
    178 
    179   @GwtIncompatible("NullPointerTester")
    180   public void testNulls() throws Exception {
    181     NullPointerTester tester = new NullPointerTester();
    182     tester.setDefault(long[].class, new long[0]);
    183     tester.setDefault(BigInteger.class, BigInteger.ZERO);
    184     tester.testAllPublicStaticMethods(UnsignedLongs.class);
    185   }
    186 }
    187