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 com.google.common.annotations.GwtCompatible; 18 import com.google.common.annotations.GwtIncompatible; 19 import com.google.common.collect.testing.Helpers; 20 import com.google.common.testing.NullPointerTester; 21 22 import junit.framework.TestCase; 23 24 import java.util.Arrays; 25 import java.util.Comparator; 26 import java.util.List; 27 import java.util.Random; 28 29 /** 30 * Tests for UnsignedInts 31 * 32 * @author Louis Wasserman 33 */ 34 @GwtCompatible(emulated = true) 35 public class UnsignedIntsTest extends TestCase { 36 private static final long[] UNSIGNED_INTS = { 37 0L, 38 1L, 39 2L, 40 3L, 41 0x12345678L, 42 0x5a4316b8L, 43 0x6cf78a4bL, 44 0xff1a618bL, 45 0xfffffffdL, 46 0xfffffffeL, 47 0xffffffffL}; 48 49 private static final int LEAST = (int) 0L; 50 private static final int GREATEST = (int) 0xffffffffL; 51 52 public void testToLong() { 53 for (long a : UNSIGNED_INTS) { 54 assertEquals(a, UnsignedInts.toLong((int) a)); 55 } 56 } 57 58 public void testCompare() { 59 for (long a : UNSIGNED_INTS) { 60 for (long b : UNSIGNED_INTS) { 61 int cmpAsLongs = Longs.compare(a, b); 62 int cmpAsUInt = UnsignedInts.compare((int) a, (int) b); 63 assertEquals(Integer.signum(cmpAsLongs), Integer.signum(cmpAsUInt)); 64 } 65 } 66 } 67 68 public void testMax_noArgs() { 69 try { 70 UnsignedInts.max(); 71 fail(); 72 } catch (IllegalArgumentException expected) { 73 } 74 } 75 76 public void testMax() { 77 assertEquals(LEAST, UnsignedInts.max(LEAST)); 78 assertEquals(GREATEST, UnsignedInts.max(GREATEST)); 79 assertEquals((int) 0xff1a618bL, UnsignedInts.max( 80 (int) 8L, (int) 6L, (int) 7L, 81 (int) 0x12345678L, (int) 0x5a4316b8L, 82 (int) 0xff1a618bL, (int) 0L)); 83 } 84 85 public void testMin_noArgs() { 86 try { 87 UnsignedInts.min(); 88 fail(); 89 } catch (IllegalArgumentException expected) { 90 } 91 } 92 93 public void testMin() { 94 assertEquals(LEAST, UnsignedInts.min(LEAST)); 95 assertEquals(GREATEST, UnsignedInts.min(GREATEST)); 96 assertEquals((int) 0L, UnsignedInts.min( 97 (int) 8L, (int) 6L, (int) 7L, 98 (int) 0x12345678L, (int) 0x5a4316b8L, 99 (int) 0xff1a618bL, (int) 0L)); 100 } 101 102 public void testLexicographicalComparator() { 103 List<int[]> ordered = Arrays.asList( 104 new int[] {}, 105 new int[] {LEAST}, 106 new int[] {LEAST, LEAST}, 107 new int[] {LEAST, (int) 1L}, 108 new int[] {(int) 1L}, 109 new int[] {(int) 1L, LEAST}, 110 new int[] {GREATEST, (GREATEST - (int) 1L)}, 111 new int[] {GREATEST, GREATEST}, 112 new int[] {GREATEST, GREATEST, GREATEST} 113 ); 114 115 Comparator<int[]> comparator = UnsignedInts.lexicographicalComparator(); 116 Helpers.testComparator(comparator, ordered); 117 } 118 119 public void testDivide() { 120 for (long a : UNSIGNED_INTS) { 121 for (long b : UNSIGNED_INTS) { 122 try { 123 assertEquals((int) (a / b), UnsignedInts.divide((int) a, (int) b)); 124 assertFalse(b == 0); 125 } catch (ArithmeticException e) { 126 assertEquals(0, b); 127 } 128 } 129 } 130 } 131 132 public void testRemainder() { 133 for (long a : UNSIGNED_INTS) { 134 for (long b : UNSIGNED_INTS) { 135 try { 136 assertEquals((int) (a % b), UnsignedInts.remainder((int) a, (int) b)); 137 assertFalse(b == 0); 138 } catch (ArithmeticException e) { 139 assertEquals(0, b); 140 } 141 } 142 } 143 } 144 145 @GwtIncompatible("Too slow in GWT (~3min fully optimized)") 146 public void testDivideRemainderEuclideanProperty() { 147 // Use a seed so that the test is deterministic: 148 Random r = new Random(0L); 149 for (int i = 0; i < 1000000; i++) { 150 int dividend = r.nextInt(); 151 int divisor = r.nextInt(); 152 // Test that the Euclidean property is preserved: 153 assertTrue(dividend 154 - (divisor * UnsignedInts.divide(dividend, divisor) + UnsignedInts.remainder(dividend, 155 divisor)) == 0); 156 } 157 } 158 159 public void testParseInt() { 160 try { 161 for (long a : UNSIGNED_INTS) { 162 assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a))); 163 } 164 } catch (NumberFormatException e) { 165 fail(e.getMessage()); 166 } 167 168 try { 169 UnsignedInts.parseUnsignedInt(Long.toString(1L << 32)); 170 fail("Expected NumberFormatException"); 171 } catch (NumberFormatException expected) {} 172 } 173 174 public void testParseIntWithRadix() throws NumberFormatException { 175 for (long a : UNSIGNED_INTS) { 176 for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) { 177 assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a, radix), radix)); 178 } 179 } 180 181 // loops through all legal radix values. 182 for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) { 183 // tests can successfully parse a number string with this radix. 184 String maxAsString = Long.toString((1L << 32) - 1, radix); 185 assertEquals(-1, UnsignedInts.parseUnsignedInt(maxAsString, radix)); 186 187 try { 188 // tests that we get exception whre an overflow would occur. 189 long overflow = 1L << 32; 190 String overflowAsString = Long.toString(overflow, radix); 191 UnsignedInts.parseUnsignedInt(overflowAsString, radix); 192 fail(); 193 } catch (NumberFormatException expected) {} 194 } 195 } 196 197 public void testParseIntThrowsExceptionForInvalidRadix() { 198 // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX, 199 // inclusive. 200 try { 201 UnsignedInts.parseUnsignedInt("0", Character.MIN_RADIX - 1); 202 fail(); 203 } catch (NumberFormatException expected) {} 204 205 try { 206 UnsignedInts.parseUnsignedInt("0", Character.MAX_RADIX + 1); 207 fail(); 208 } catch (NumberFormatException expected) {} 209 210 // The radix is used as an array index, so try a negative value. 211 try { 212 UnsignedInts.parseUnsignedInt("0", -1); 213 fail(); 214 } catch (NumberFormatException expected) {} 215 } 216 217 public void testDecodeInt() { 218 assertEquals(0xffffffff, UnsignedInts.decode("0xffffffff")); 219 assertEquals(01234567, UnsignedInts.decode("01234567")); // octal 220 assertEquals(0x12345678, UnsignedInts.decode("#12345678")); 221 assertEquals(76543210, UnsignedInts.decode("76543210")); 222 assertEquals(0x13579135, UnsignedInts.decode("0x13579135")); 223 assertEquals(0x13579135, UnsignedInts.decode("0X13579135")); 224 assertEquals(0, UnsignedInts.decode("0")); 225 } 226 227 public void testDecodeIntFails() { 228 try { 229 // One more than maximum value 230 UnsignedInts.decode("0xfffffffff"); 231 fail(); 232 } catch (NumberFormatException expected) { 233 } 234 235 try { 236 UnsignedInts.decode("-5"); 237 fail(); 238 } catch (NumberFormatException expected) { 239 } 240 241 try { 242 UnsignedInts.decode("-0x5"); 243 fail(); 244 } catch (NumberFormatException expected) { 245 } 246 247 try { 248 UnsignedInts.decode("-05"); 249 fail(); 250 } catch (NumberFormatException expected) { 251 } 252 } 253 254 public void testToString() { 255 int[] bases = {2, 5, 7, 8, 10, 16}; 256 for (long a : UNSIGNED_INTS) { 257 for (int base : bases) { 258 assertEquals(UnsignedInts.toString((int) a, base), Long.toString(a, base)); 259 } 260 } 261 } 262 263 public void testJoin() { 264 assertEquals("", join()); 265 assertEquals("1", join(1)); 266 assertEquals("1,2", join(1, 2)); 267 assertEquals("4294967295,2147483648", join(-1, Integer.MIN_VALUE)); 268 269 assertEquals("123", UnsignedInts.join("", 1, 2, 3)); 270 } 271 272 private static String join(int... values) { 273 return UnsignedInts.join(",", values); 274 } 275 276 @GwtIncompatible("NullPointerTester") 277 public void testNulls() { 278 new NullPointerTester().testAllPublicStaticMethods(UnsignedInts.class); 279 } 280 } 281