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 com.google.common.annotations.GwtCompatible; 20 import com.google.common.annotations.GwtIncompatible; 21 import com.google.common.collect.testing.Helpers; 22 import com.google.common.testing.NullPointerTester; 23 24 import junit.framework.TestCase; 25 26 import java.math.BigInteger; 27 import java.util.Arrays; 28 import java.util.Comparator; 29 import java.util.List; 30 import java.util.Random; 31 32 /** 33 * Tests for UnsignedLongs 34 * 35 * @author Brian Milch 36 * @author Louis Wasserman 37 */ 38 @GwtCompatible(emulated = true) 39 public class UnsignedLongsTest extends TestCase { 40 private static final long LEAST = 0L; 41 private static final long GREATEST = 0xffffffffffffffffL; 42 testCompare()43 public void testCompare() { 44 // max value 45 assertTrue(UnsignedLongs.compare(0, 0xffffffffffffffffL) < 0); 46 assertTrue(UnsignedLongs.compare(0xffffffffffffffffL, 0) > 0); 47 48 // both with high bit set 49 assertTrue(UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xffffffffffffffffL) < 0); 50 assertTrue(UnsignedLongs.compare(0xffffffffffffffffL, 0xff1a618b7f65ea12L) > 0); 51 52 // one with high bit set 53 assertTrue(UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0xff1a618b7f65ea12L) < 0); 54 assertTrue(UnsignedLongs.compare(0xff1a618b7f65ea12L, 0x5a4316b8c153ac4dL) > 0); 55 56 // neither with high bit set 57 assertTrue(UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0x6cf78a4b139a4e2aL) < 0); 58 assertTrue(UnsignedLongs.compare(0x6cf78a4b139a4e2aL, 0x5a4316b8c153ac4dL) > 0); 59 60 // same value 61 assertTrue(UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xff1a618b7f65ea12L) == 0); 62 } 63 testMax_noArgs()64 public void testMax_noArgs() { 65 try { 66 UnsignedLongs.max(); 67 fail(); 68 } catch (IllegalArgumentException expected) { 69 } 70 } 71 testMax()72 public void testMax() { 73 assertEquals(LEAST, UnsignedLongs.max(LEAST)); 74 assertEquals(GREATEST, UnsignedLongs.max(GREATEST)); 75 assertEquals(0xff1a618b7f65ea12L, UnsignedLongs.max( 76 0x5a4316b8c153ac4dL, 8L, 100L, 77 0L, 0x6cf78a4b139a4e2aL, 0xff1a618b7f65ea12L)); 78 } 79 testMin_noArgs()80 public void testMin_noArgs() { 81 try { 82 UnsignedLongs.min(); 83 fail(); 84 } catch (IllegalArgumentException expected) { 85 } 86 } 87 testMin()88 public void testMin() { 89 assertEquals(LEAST, UnsignedLongs.min(LEAST)); 90 assertEquals(GREATEST, UnsignedLongs.min(GREATEST)); 91 assertEquals(0L, UnsignedLongs.min( 92 0x5a4316b8c153ac4dL, 8L, 100L, 93 0L, 0x6cf78a4b139a4e2aL, 0xff1a618b7f65ea12L)); 94 } 95 testLexicographicalComparator()96 public void testLexicographicalComparator() { 97 List<long[]> ordered = Arrays.asList( 98 new long[] {}, 99 new long[] {LEAST}, 100 new long[] {LEAST, LEAST}, 101 new long[] {LEAST, (long) 1}, 102 new long[] {(long) 1}, 103 new long[] {(long) 1, LEAST}, 104 new long[] {GREATEST, GREATEST - (long) 1}, 105 new long[] {GREATEST, GREATEST}, 106 new long[] {GREATEST, GREATEST, GREATEST}); 107 108 Comparator<long[]> comparator = UnsignedLongs.lexicographicalComparator(); 109 Helpers.testComparator(comparator, ordered); 110 } 111 testDivide()112 public void testDivide() { 113 assertEquals(2, UnsignedLongs.divide(14, 5)); 114 assertEquals(0, UnsignedLongs.divide(0, 50)); 115 assertEquals(1, UnsignedLongs.divide(0xfffffffffffffffeL, 0xfffffffffffffffdL)); 116 assertEquals(0, UnsignedLongs.divide(0xfffffffffffffffdL, 0xfffffffffffffffeL)); 117 assertEquals(281479271743488L, UnsignedLongs.divide(0xfffffffffffffffeL, 65535)); 118 assertEquals(0x7fffffffffffffffL, UnsignedLongs.divide(0xfffffffffffffffeL, 2)); 119 assertEquals(3689348814741910322L, UnsignedLongs.divide(0xfffffffffffffffeL, 5)); 120 } 121 testRemainder()122 public void testRemainder() { 123 assertEquals(4, UnsignedLongs.remainder(14, 5)); 124 assertEquals(0, UnsignedLongs.remainder(0, 50)); 125 assertEquals(1, UnsignedLongs.remainder(0xfffffffffffffffeL, 0xfffffffffffffffdL)); 126 assertEquals(0xfffffffffffffffdL, 127 UnsignedLongs.remainder(0xfffffffffffffffdL, 0xfffffffffffffffeL)); 128 assertEquals(65534L, UnsignedLongs.remainder(0xfffffffffffffffeL, 65535)); 129 assertEquals(0, UnsignedLongs.remainder(0xfffffffffffffffeL, 2)); 130 assertEquals(4, UnsignedLongs.remainder(0xfffffffffffffffeL, 5)); 131 } 132 133 @GwtIncompatible("Too slow in GWT (~3min fully optimized)") testDivideRemainderEuclideanProperty()134 public void testDivideRemainderEuclideanProperty() { 135 // Use a seed so that the test is deterministic: 136 Random r = new Random(0L); 137 for (int i = 0; i < 1000000; i++) { 138 long dividend = r.nextLong(); 139 long divisor = r.nextLong(); 140 // Test that the Euclidean property is preserved: 141 assertEquals(0, 142 dividend - (divisor * UnsignedLongs.divide(dividend, divisor) 143 + UnsignedLongs.remainder(dividend, divisor))); 144 } 145 } 146 testParseLong()147 public void testParseLong() { 148 assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("18446744073709551615")); 149 assertEquals(0x7fffffffffffffffL, UnsignedLongs.parseUnsignedLong("9223372036854775807")); 150 assertEquals(0xff1a618b7f65ea12L, UnsignedLongs.parseUnsignedLong("18382112080831834642")); 151 assertEquals(0x5a4316b8c153ac4dL, UnsignedLongs.parseUnsignedLong("6504067269626408013")); 152 assertEquals(0x6cf78a4b139a4e2aL, UnsignedLongs.parseUnsignedLong("7851896530399809066")); 153 154 try { 155 // One more than maximum value 156 UnsignedLongs.parseUnsignedLong("18446744073709551616"); 157 fail(); 158 } catch (NumberFormatException expected) { 159 } 160 } 161 testDecodeLong()162 public void testDecodeLong() { 163 assertEquals(0xffffffffffffffffL, UnsignedLongs.decode("0xffffffffffffffff")); 164 assertEquals(01234567, UnsignedLongs.decode("01234567")); // octal 165 assertEquals(0x1234567890abcdefL, UnsignedLongs.decode("#1234567890abcdef")); 166 assertEquals(987654321012345678L, UnsignedLongs.decode("987654321012345678")); 167 assertEquals(0x135791357913579L, UnsignedLongs.decode("0x135791357913579")); 168 assertEquals(0x135791357913579L, UnsignedLongs.decode("0X135791357913579")); 169 assertEquals(0L, UnsignedLongs.decode("0")); 170 } 171 testDecodeLongFails()172 public void testDecodeLongFails() { 173 try { 174 // One more than maximum value 175 UnsignedLongs.decode("0xfffffffffffffffff"); 176 fail(); 177 } catch (NumberFormatException expected) { 178 } 179 180 try { 181 UnsignedLongs.decode("-5"); 182 fail(); 183 } catch (NumberFormatException expected) { 184 } 185 186 try { 187 UnsignedLongs.decode("-0x5"); 188 fail(); 189 } catch (NumberFormatException expected) { 190 } 191 192 try { 193 UnsignedLongs.decode("-05"); 194 fail(); 195 } catch (NumberFormatException expected) { 196 } 197 } 198 testParseLongWithRadix()199 public void testParseLongWithRadix() { 200 assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("ffffffffffffffff", 16)); 201 assertEquals(0x1234567890abcdefL, UnsignedLongs.parseUnsignedLong("1234567890abcdef", 16)); 202 203 BigInteger max = BigInteger.ZERO.setBit(64).subtract(ONE); 204 // loops through all legal radix values. 205 for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) { 206 // tests can successfully parse a number string with this radix. 207 String maxAsString = max.toString(radix); 208 assertEquals(max.longValue(), UnsignedLongs.parseUnsignedLong(maxAsString, radix)); 209 210 try { 211 // tests that we get exception whre an overflow would occur. 212 BigInteger overflow = max.add(ONE); 213 String overflowAsString = overflow.toString(radix); 214 UnsignedLongs.parseUnsignedLong(overflowAsString, radix); 215 fail(); 216 } catch (NumberFormatException expected) { 217 } 218 } 219 220 try { 221 UnsignedLongs.parseUnsignedLong("1234567890abcdef1", 16); 222 fail(); 223 } catch (NumberFormatException expected) { 224 } 225 } 226 testParseLongThrowsExceptionForInvalidRadix()227 public void testParseLongThrowsExceptionForInvalidRadix() { 228 // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX, inclusive. 229 try { 230 UnsignedLongs.parseUnsignedLong("0", Character.MIN_RADIX - 1); 231 fail(); 232 } catch (NumberFormatException expected) { 233 } 234 235 try { 236 UnsignedLongs.parseUnsignedLong("0", Character.MAX_RADIX + 1); 237 fail(); 238 } catch (NumberFormatException expected) { 239 } 240 241 // The radix is used as an array index, so try a negative value. 242 try { 243 UnsignedLongs.parseUnsignedLong("0", -1); 244 fail(); 245 } catch (NumberFormatException expected) { 246 } 247 } 248 testToString()249 public void testToString() { 250 String[] tests = { 251 "ffffffffffffffff", 252 "7fffffffffffffff", 253 "ff1a618b7f65ea12", 254 "5a4316b8c153ac4d", 255 "6cf78a4b139a4e2a" 256 }; 257 int[] bases = { 2, 5, 7, 8, 10, 16 }; 258 for (int base : bases) { 259 for (String x : tests) { 260 BigInteger xValue = new BigInteger(x, 16); 261 long xLong = xValue.longValue(); // signed 262 assertEquals(xValue.toString(base), UnsignedLongs.toString(xLong, base)); 263 } 264 } 265 } 266 testJoin()267 public void testJoin() { 268 assertEquals("", UnsignedLongs.join(",")); 269 assertEquals("1", UnsignedLongs.join(",", 1)); 270 assertEquals("1,2", UnsignedLongs.join(",", 1, 2)); 271 assertEquals("18446744073709551615,9223372036854775808", 272 UnsignedLongs.join(",", -1, Long.MIN_VALUE)); 273 assertEquals("123", UnsignedLongs.join("", 1, 2, 3)); 274 assertEquals("184467440737095516159223372036854775808", 275 UnsignedLongs.join("", -1, Long.MIN_VALUE)); 276 } 277 278 @GwtIncompatible("NullPointerTester") testNulls()279 public void testNulls() { 280 new NullPointerTester().testAllPublicStaticMethods(UnsignedLongs.class); 281 } 282 } 283