• 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   @J2ktIncompatible
199   @GwtIncompatible // Too slow in GWT (~3min fully optimized)
testDivideRemainderEuclideanProperty()200   public void testDivideRemainderEuclideanProperty() {
201     // Use a seed so that the test is deterministic:
202     Random r = new Random(0L);
203     for (int i = 0; i < 1000000; i++) {
204       long dividend = r.nextLong();
205       long divisor = r.nextLong();
206       // Test that the Euclidean property is preserved:
207       assertThat(
208               dividend
209                   - (divisor * UnsignedLongs.divide(dividend, divisor)
210                       + UnsignedLongs.remainder(dividend, divisor)))
211           .isEqualTo(0);
212     }
213   }
214 
testParseLong()215   public void testParseLong() {
216     assertThat(UnsignedLongs.parseUnsignedLong("18446744073709551615"))
217         .isEqualTo(0xffffffffffffffffL);
218     assertThat(UnsignedLongs.parseUnsignedLong("9223372036854775807"))
219         .isEqualTo(0x7fffffffffffffffL);
220     assertThat(UnsignedLongs.parseUnsignedLong("18382112080831834642"))
221         .isEqualTo(0xff1a618b7f65ea12L);
222     assertThat(UnsignedLongs.parseUnsignedLong("6504067269626408013"))
223         .isEqualTo(0x5a4316b8c153ac4dL);
224     assertThat(UnsignedLongs.parseUnsignedLong("7851896530399809066"))
225         .isEqualTo(0x6cf78a4b139a4e2aL);
226   }
227 
testParseLongEmptyString()228   public void testParseLongEmptyString() {
229     try {
230       UnsignedLongs.parseUnsignedLong("");
231       fail("NumberFormatException should have been raised.");
232     } catch (NumberFormatException expected) {
233     }
234   }
235 
testParseLongFails()236   public void testParseLongFails() {
237     try {
238       // One more than maximum value
239       UnsignedLongs.parseUnsignedLong("18446744073709551616");
240       fail();
241     } catch (NumberFormatException expected) {
242     }
243   }
244 
testDecodeLong()245   public void testDecodeLong() {
246     assertThat(UnsignedLongs.decode("0xffffffffffffffff")).isEqualTo(0xffffffffffffffffL);
247     assertThat(UnsignedLongs.decode("01234567")).isEqualTo(01234567); // octal
248     assertThat(UnsignedLongs.decode("#1234567890abcdef")).isEqualTo(0x1234567890abcdefL);
249     assertThat(UnsignedLongs.decode("987654321012345678")).isEqualTo(987654321012345678L);
250     assertThat(UnsignedLongs.decode("0x135791357913579")).isEqualTo(0x135791357913579L);
251     assertThat(UnsignedLongs.decode("0X135791357913579")).isEqualTo(0x135791357913579L);
252     assertThat(UnsignedLongs.decode("0")).isEqualTo(0L);
253   }
254 
testDecodeLongFails()255   public void testDecodeLongFails() {
256     try {
257       // One more than maximum value
258       UnsignedLongs.decode("0xfffffffffffffffff");
259       fail();
260     } catch (NumberFormatException expected) {
261     }
262 
263     try {
264       UnsignedLongs.decode("-5");
265       fail();
266     } catch (NumberFormatException expected) {
267     }
268 
269     try {
270       UnsignedLongs.decode("-0x5");
271       fail();
272     } catch (NumberFormatException expected) {
273     }
274 
275     try {
276       UnsignedLongs.decode("-05");
277       fail();
278     } catch (NumberFormatException expected) {
279     }
280   }
281 
testParseLongWithRadix()282   public void testParseLongWithRadix() {
283     assertThat(UnsignedLongs.parseUnsignedLong("ffffffffffffffff", 16))
284         .isEqualTo(0xffffffffffffffffL);
285     assertThat(UnsignedLongs.parseUnsignedLong("1234567890abcdef", 16))
286         .isEqualTo(0x1234567890abcdefL);
287   }
288 
testParseLongWithRadixLimits()289   public void testParseLongWithRadixLimits() {
290     BigInteger max = BigInteger.ZERO.setBit(64).subtract(ONE);
291     // loops through all legal radix values.
292     for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
293       // tests can successfully parse a number string with this radix.
294       String maxAsString = max.toString(radix);
295       assertThat(UnsignedLongs.parseUnsignedLong(maxAsString, radix)).isEqualTo(max.longValue());
296 
297       try {
298         // tests that we get exception where an overflow would occur.
299         BigInteger overflow = max.add(ONE);
300         String overflowAsString = overflow.toString(radix);
301         UnsignedLongs.parseUnsignedLong(overflowAsString, radix);
302         fail();
303       } catch (NumberFormatException expected) {
304       }
305     }
306 
307     try {
308       UnsignedLongs.parseUnsignedLong("1234567890abcdef1", 16);
309       fail();
310     } catch (NumberFormatException expected) {
311     }
312   }
313 
testParseLongThrowsExceptionForInvalidRadix()314   public void testParseLongThrowsExceptionForInvalidRadix() {
315     // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX, inclusive.
316     try {
317       UnsignedLongs.parseUnsignedLong("0", Character.MIN_RADIX - 1);
318       fail();
319     } catch (NumberFormatException expected) {
320     }
321 
322     try {
323       UnsignedLongs.parseUnsignedLong("0", Character.MAX_RADIX + 1);
324       fail();
325     } catch (NumberFormatException expected) {
326     }
327 
328     // The radix is used as an array index, so try a negative value.
329     try {
330       UnsignedLongs.parseUnsignedLong("0", -1);
331       fail();
332     } catch (NumberFormatException expected) {
333     }
334   }
335 
336   @J2ktIncompatible // TODO(b/285562794): Wrong result for j2kt
testToString()337   public void testToString() {
338     String[] tests = {
339       "0",
340       "ffffffffffffffff",
341       "7fffffffffffffff",
342       "ff1a618b7f65ea12",
343       "5a4316b8c153ac4d",
344       "6cf78a4b139a4e2a"
345     };
346     int[] bases = {2, 5, 7, 8, 10, 16};
347     for (int base : bases) {
348       for (String x : tests) {
349         BigInteger xValue = new BigInteger(x, 16);
350         long xLong = xValue.longValue(); // signed
351         assertThat(UnsignedLongs.toString(xLong, base)).isEqualTo(xValue.toString(base));
352       }
353     }
354   }
355 
testJoin()356   public void testJoin() {
357     assertThat(UnsignedLongs.join(",")).isEmpty();
358     assertThat(UnsignedLongs.join(",", 1)).isEqualTo("1");
359     assertThat(UnsignedLongs.join(",", 1, 2)).isEqualTo("1,2");
360     assertThat(UnsignedLongs.join(",", -1, Long.MIN_VALUE))
361         .isEqualTo("18446744073709551615,9223372036854775808");
362     assertThat(UnsignedLongs.join("", 1, 2, 3)).isEqualTo("123");
363     assertThat(UnsignedLongs.join("", -1, Long.MIN_VALUE))
364         .isEqualTo("184467440737095516159223372036854775808");
365   }
366 
367   @J2ktIncompatible
368   @GwtIncompatible // NullPointerTester
testNulls()369   public void testNulls() {
370     new NullPointerTester().testAllPublicStaticMethods(UnsignedLongs.class);
371   }
372 }
373