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