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 15package com.google.common.primitives; 16 17import static java.math.BigInteger.ONE; 18 19import java.math.BigInteger; 20import java.util.Random; 21 22import junit.framework.TestCase; 23 24import com.google.common.annotations.GwtCompatible; 25import com.google.common.annotations.GwtIncompatible; 26import 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) 35public 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