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