View Javadoc
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 License
10   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11   * or implied. See the License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  
15  package com.google.common.primitives;
16  
17  import static com.google.common.base.Preconditions.checkArgument;
18  import static com.google.common.base.Preconditions.checkNotNull;
19  import static com.google.common.base.Preconditions.checkPositionIndexes;
20  
21  import com.google.common.annotations.Beta;
22  import com.google.common.annotations.GwtCompatible;
23  import com.google.errorprone.annotations.CanIgnoreReturnValue;
24  import java.math.BigInteger;
25  import java.util.Arrays;
26  import java.util.Comparator;
27  
28  /**
29   * Static utility methods pertaining to {@code long} primitives that interpret values as
30   * <i>unsigned</i> (that is, any negative value {@code x} is treated as the positive value
31   * {@code 2^64 + x}). The methods for which signedness is not an issue are in {@link Longs}, as well
32   * as signed versions of methods for which signedness is an issue.
33   *
34   * <p>In addition, this class provides several static methods for converting a {@code long} to a
35   * {@code String} and a {@code String} to a {@code long} that treat the {@code long} as an unsigned
36   * number.
37   *
38   * <p>Users of these utilities must be <i>extremely careful</i> not to mix up signed and unsigned
39   * {@code long} values. When possible, it is recommended that the {@link UnsignedLong} wrapper class
40   * be used, at a small efficiency penalty, to enforce the distinction in the type system.
41   *
42   * <p>See the Guava User Guide article on
43   * <a href="https://github.com/google/guava/wiki/PrimitivesExplained#unsigned-support">unsigned
44   * primitive utilities</a>.
45   *
46   * @author Louis Wasserman
47   * @author Brian Milch
48   * @author Colin Evans
49   * @since 10.0
50   */
51  @Beta
52  @GwtCompatible
53  public final class UnsignedLongs {
54    private UnsignedLongs() {}
55  
56    public static final long MAX_VALUE = -1L; // Equivalent to 2^64 - 1
57  
58    /**
59     * A (self-inverse) bijection which converts the ordering on unsigned longs to the ordering on
60     * longs, that is, {@code a <= b} as unsigned longs if and only if {@code flip(a) <= flip(b)} as
61     * signed longs.
62     */
63    private static long flip(long a) {
64      return a ^ Long.MIN_VALUE;
65    }
66  
67    /**
68     * Compares the two specified {@code long} values, treating them as unsigned values between
69     * {@code 0} and {@code 2^64 - 1} inclusive.
70     *
71     * <p><b>Java 8 users:</b> use {@link Long#compareUnsigned(long, long)} instead.
72     *
73     * @param a the first unsigned {@code long} to compare
74     * @param b the second unsigned {@code long} to compare
75     * @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is
76     *     greater than {@code b}; or zero if they are equal
77     */
78    public static int compare(long a, long b) {
79      return Longs.compare(flip(a), flip(b));
80    }
81  
82    /**
83     * Returns the least value present in {@code array}, treating values as unsigned.
84     *
85     * @param array a <i>nonempty</i> array of unsigned {@code long} values
86     * @return the value present in {@code array} that is less than or equal to every other value in
87     *     the array according to {@link #compare}
88     * @throws IllegalArgumentException if {@code array} is empty
89     */
90    public static long min(long... array) {
91      checkArgument(array.length > 0);
92      long min = flip(array[0]);
93      for (int i = 1; i < array.length; i++) {
94        long next = flip(array[i]);
95        if (next < min) {
96          min = next;
97        }
98      }
99      return flip(min);
100   }
101 
102   /**
103    * Returns the greatest value present in {@code array}, treating values as unsigned.
104    *
105    * @param array a <i>nonempty</i> array of unsigned {@code long} values
106    * @return the value present in {@code array} that is greater than or equal to every other value
107    *     in the array according to {@link #compare}
108    * @throws IllegalArgumentException if {@code array} is empty
109    */
110   public static long max(long... array) {
111     checkArgument(array.length > 0);
112     long max = flip(array[0]);
113     for (int i = 1; i < array.length; i++) {
114       long next = flip(array[i]);
115       if (next > max) {
116         max = next;
117       }
118     }
119     return flip(max);
120   }
121 
122   /**
123    * Returns a string containing the supplied unsigned {@code long} values separated by
124    * {@code separator}. For example, {@code join("-", 1, 2, 3)} returns the string {@code "1-2-3"}.
125    *
126    * @param separator the text that should appear between consecutive values in the resulting string
127    *     (but not at the start or end)
128    * @param array an array of unsigned {@code long} values, possibly empty
129    */
130   public static String join(String separator, long... array) {
131     checkNotNull(separator);
132     if (array.length == 0) {
133       return "";
134     }
135 
136     // For pre-sizing a builder, just get the right order of magnitude
137     StringBuilder builder = new StringBuilder(array.length * 5);
138     builder.append(toString(array[0]));
139     for (int i = 1; i < array.length; i++) {
140       builder.append(separator).append(toString(array[i]));
141     }
142     return builder.toString();
143   }
144 
145   /**
146    * Returns a comparator that compares two arrays of unsigned {@code long} values <a
147    * href="http://en.wikipedia.org/wiki/Lexicographical_order">lexicographically</a>. That is, it
148    * compares, using {@link #compare(long, long)}), the first pair of values that follow any common
149    * prefix, or when one array is a prefix of the other, treats the shorter array as the lesser. For
150    * example, {@code [] < [1L] < [1L, 2L] < [2L] < [1L << 63]}.
151    *
152    * <p>The returned comparator is inconsistent with {@link Object#equals(Object)} (since arrays
153    * support only identity equality), but it is consistent with
154    * {@link Arrays#equals(long[], long[])}.
155    */
156   public static Comparator<long[]> lexicographicalComparator() {
157     return LexicographicalComparator.INSTANCE;
158   }
159 
160   enum LexicographicalComparator implements Comparator<long[]> {
161     INSTANCE;
162 
163     @Override
164     public int compare(long[] left, long[] right) {
165       int minLength = Math.min(left.length, right.length);
166       for (int i = 0; i < minLength; i++) {
167         if (left[i] != right[i]) {
168           return UnsignedLongs.compare(left[i], right[i]);
169         }
170       }
171       return left.length - right.length;
172     }
173 
174     @Override
175     public String toString() {
176       return "UnsignedLongs.lexicographicalComparator()";
177     }
178   }
179   /**
180    * Sorts the array, treating its elements as unsigned 64-bit integers.
181    *
182    * @since 23.1
183    */
184   public static void sort(long[] array) {
185     checkNotNull(array);
186     sort(array, 0, array.length);
187   }
188 
189   /**
190    * Sorts the array between {@code fromIndex} inclusive and {@code toIndex} exclusive, treating its
191    * elements as unsigned 64-bit integers.
192    *
193    * @since 23.1
194    */
195   public static void sort(long[] array, int fromIndex, int toIndex) {
196     checkNotNull(array);
197     checkPositionIndexes(fromIndex, toIndex, array.length);
198     for (int i = fromIndex; i < toIndex; i++) {
199       array[i] = flip(array[i]);
200     }
201     Arrays.sort(array, fromIndex, toIndex);
202     for (int i = fromIndex; i < toIndex; i++) {
203       array[i] = flip(array[i]);
204     }
205   }
206 
207   /**
208    * Sorts the elements of {@code array} in descending order, interpreting them as unsigned 64-bit
209    * integers.
210    *
211    * @since 23.1
212    */
213   public static void sortDescending(long[] array) {
214     checkNotNull(array);
215     sortDescending(array, 0, array.length);
216   }
217 
218   /**
219    * Sorts the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex}
220    * exclusive in descending order, interpreting them as unsigned 64-bit integers.
221    *
222    * @since 23.1
223    */
224   public static void sortDescending(long[] array, int fromIndex, int toIndex) {
225     checkNotNull(array);
226     checkPositionIndexes(fromIndex, toIndex, array.length);
227     for (int i = fromIndex; i < toIndex; i++) {
228       array[i] ^= Long.MAX_VALUE;
229     }
230     Arrays.sort(array, fromIndex, toIndex);
231     for (int i = fromIndex; i < toIndex; i++) {
232       array[i] ^= Long.MAX_VALUE;
233     }
234   }
235 
236   /**
237    * Returns dividend / divisor, where the dividend and divisor are treated as unsigned 64-bit
238    * quantities.
239    *
240    * <p><b>Java 8 users:</b> use {@link Long#divideUnsigned(long, long)} instead.
241    *
242    * @param dividend the dividend (numerator)
243    * @param divisor the divisor (denominator)
244    * @throws ArithmeticException if divisor is 0
245    */
246   public static long divide(long dividend, long divisor) {
247     if (divisor < 0) { // i.e., divisor >= 2^63:
248       if (compare(dividend, divisor) < 0) {
249         return 0; // dividend < divisor
250       } else {
251         return 1; // dividend >= divisor
252       }
253     }
254 
255     // Optimization - use signed division if dividend < 2^63
256     if (dividend >= 0) {
257       return dividend / divisor;
258     }
259 
260     /*
261      * Otherwise, approximate the quotient, check, and correct if necessary. Our approximation is
262      * guaranteed to be either exact or one less than the correct value. This follows from fact that
263      * floor(floor(x)/i) == floor(x/i) for any real x and integer i != 0. The proof is not quite
264      * trivial.
265      */
266     long quotient = ((dividend >>> 1) / divisor) << 1;
267     long rem = dividend - quotient * divisor;
268     return quotient + (compare(rem, divisor) >= 0 ? 1 : 0);
269   }
270 
271   /**
272    * Returns dividend % divisor, where the dividend and divisor are treated as unsigned 64-bit
273    * quantities.
274    *
275    * <p><b>Java 8 users:</b> use {@link Long#remainderUnsigned(long, long)} instead.
276    *
277    * @param dividend the dividend (numerator)
278    * @param divisor the divisor (denominator)
279    * @throws ArithmeticException if divisor is 0
280    * @since 11.0
281    */
282   public static long remainder(long dividend, long divisor) {
283     if (divisor < 0) { // i.e., divisor >= 2^63:
284       if (compare(dividend, divisor) < 0) {
285         return dividend; // dividend < divisor
286       } else {
287         return dividend - divisor; // dividend >= divisor
288       }
289     }
290 
291     // Optimization - use signed modulus if dividend < 2^63
292     if (dividend >= 0) {
293       return dividend % divisor;
294     }
295 
296     /*
297      * Otherwise, approximate the quotient, check, and correct if necessary. Our approximation is
298      * guaranteed to be either exact or one less than the correct value. This follows from the fact
299      * that floor(floor(x)/i) == floor(x/i) for any real x and integer i != 0. The proof is not
300      * quite trivial.
301      */
302     long quotient = ((dividend >>> 1) / divisor) << 1;
303     long rem = dividend - quotient * divisor;
304     return rem - (compare(rem, divisor) >= 0 ? divisor : 0);
305   }
306 
307   /**
308    * Returns the unsigned {@code long} value represented by the given decimal string.
309    *
310    * <p><b>Java 8 users:</b> use {@link Long#parseUnsignedLong(String)} instead.
311    *
312    * @throws NumberFormatException if the string does not contain a valid unsigned {@code long}
313    *     value
314    * @throws NullPointerException if {@code string} is null (in contrast to
315    *     {@link Long#parseLong(String)})
316    */
317   @CanIgnoreReturnValue
318   public static long parseUnsignedLong(String string) {
319     return parseUnsignedLong(string, 10);
320   }
321 
322   /**
323    * Returns the unsigned {@code long} value represented by the given string.
324    *
325    * Accepts a decimal, hexadecimal, or octal number given by specifying the following prefix:
326    *
327    * <ul>
328    * <li>{@code 0x}<i>HexDigits</i>
329    * <li>{@code 0X}<i>HexDigits</i>
330    * <li>{@code #}<i>HexDigits</i>
331    * <li>{@code 0}<i>OctalDigits</i>
332    * </ul>
333    *
334    * @throws NumberFormatException if the string does not contain a valid unsigned {@code long}
335    *     value
336    * @since 13.0
337    */
338   @CanIgnoreReturnValue
339   public static long decode(String stringValue) {
340     ParseRequest request = ParseRequest.fromString(stringValue);
341 
342     try {
343       return parseUnsignedLong(request.rawValue, request.radix);
344     } catch (NumberFormatException e) {
345       NumberFormatException decodeException =
346           new NumberFormatException("Error parsing value: " + stringValue);
347       decodeException.initCause(e);
348       throw decodeException;
349     }
350   }
351 
352   /**
353    * Returns the unsigned {@code long} value represented by a string with the given radix.
354    *
355    * <p><b>Java 8 users:</b> use {@link Long#parseUnsignedLong(String, int)} instead.
356    *
357    * @param string the string containing the unsigned {@code long} representation to be parsed.
358    * @param radix the radix to use while parsing {@code string}
359    * @throws NumberFormatException if the string does not contain a valid unsigned {@code long} with
360    *     the given radix, or if {@code radix} is not between {@link Character#MIN_RADIX} and
361    *     {@link Character#MAX_RADIX}.
362    * @throws NullPointerException if {@code string} is null (in contrast to
363    *     {@link Long#parseLong(String)})
364    */
365   @CanIgnoreReturnValue
366   public static long parseUnsignedLong(String string, int radix) {
367     checkNotNull(string);
368     if (string.length() == 0) {
369       throw new NumberFormatException("empty string");
370     }
371     if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
372       throw new NumberFormatException("illegal radix: " + radix);
373     }
374 
375     int maxSafePos = ParseOverflowDetection.maxSafeDigits[radix] - 1;
376     long value = 0;
377     for (int pos = 0; pos < string.length(); pos++) {
378       int digit = Character.digit(string.charAt(pos), radix);
379       if (digit == -1) {
380         throw new NumberFormatException(string);
381       }
382       if (pos > maxSafePos && ParseOverflowDetection.overflowInParse(value, digit, radix)) {
383         throw new NumberFormatException("Too large for unsigned long: " + string);
384       }
385       value = (value * radix) + digit;
386     }
387 
388     return value;
389   }
390   
391   /*
392    * We move the static constants into this class so ProGuard can inline UnsignedLongs entirely
393    * unless the user is actually calling a parse method.
394    */
395   private static final class ParseOverflowDetection {
396     private ParseOverflowDetection() {}
397     
398     // calculated as 0xffffffffffffffff / radix
399     static final long[] maxValueDivs = new long[Character.MAX_RADIX + 1];
400     static final int[] maxValueMods = new int[Character.MAX_RADIX + 1];
401     static final int[] maxSafeDigits = new int[Character.MAX_RADIX + 1];
402 
403     static {
404       BigInteger overflow = new BigInteger("10000000000000000", 16);
405       for (int i = Character.MIN_RADIX; i <= Character.MAX_RADIX; i++) {
406         maxValueDivs[i] = divide(MAX_VALUE, i);
407         maxValueMods[i] = (int) remainder(MAX_VALUE, i);
408         maxSafeDigits[i] = overflow.toString(i).length() - 1;
409       }
410     }
411 
412     /**
413      * Returns true if (current * radix) + digit is a number too large to be represented by an
414      * unsigned long. This is useful for detecting overflow while parsing a string representation of
415      * a number. Does not verify whether supplied radix is valid, passing an invalid radix will give
416      * undefined results or an ArrayIndexOutOfBoundsException.
417      */
418     static boolean overflowInParse(long current, int digit, int radix) {
419       if (current >= 0) {
420         if (current < maxValueDivs[radix]) {
421           return false;
422         }
423         if (current > maxValueDivs[radix]) {
424           return true;
425         }
426         // current == maxValueDivs[radix]
427         return (digit > maxValueMods[radix]);
428       }
429 
430       // current < 0: high bit is set
431       return true;
432     }
433   }
434 
435   /**
436    * Returns a string representation of x, where x is treated as unsigned.
437    *
438    * <p><b>Java 8 users:</b> use {@link Long#toUnsignedString(long)} instead.
439    */
440   public static String toString(long x) {
441     return toString(x, 10);
442   }
443 
444   /**
445    * Returns a string representation of {@code x} for the given radix, where {@code x} is treated as
446    * unsigned.
447    *
448    * <p><b>Java 8 users:</b> use {@link Long#toUnsignedString(long, int)} instead.
449    *
450    * @param x the value to convert to a string.
451    * @param radix the radix to use while working with {@code x}
452    * @throws IllegalArgumentException if {@code radix} is not between {@link Character#MIN_RADIX}
453    *     and {@link Character#MAX_RADIX}.
454    */
455   public static String toString(long x, int radix) {
456     checkArgument(
457         radix >= Character.MIN_RADIX && radix <= Character.MAX_RADIX,
458         "radix (%s) must be between Character.MIN_RADIX and Character.MAX_RADIX",
459         radix);
460     if (x == 0) {
461       // Simply return "0"
462       return "0";
463     } else if (x > 0) {
464       return Long.toString(x, radix);
465     } else {
466       char[] buf = new char[64];
467       int i = buf.length;
468       if ((radix & (radix - 1)) == 0) {
469         // Radix is a power of two so we can avoid division.
470         int shift = Integer.numberOfTrailingZeros(radix);
471         int mask = radix - 1;
472         do {
473           buf[--i] = Character.forDigit(((int) x) & mask, radix);
474           x >>>= shift;
475         } while (x != 0);
476       } else {
477         // Separate off the last digit using unsigned division. That will leave
478         // a number that is nonnegative as a signed integer.
479         long quotient;
480         if ((radix & 1) == 0) {
481           // Fast path for the usual case where the radix is even.
482           quotient = (x >>> 1) / (radix >>> 1);
483         } else {
484           quotient = divide(x, radix);
485         }
486         long rem = x - quotient * radix;
487         buf[--i] = Character.forDigit((int) rem, radix);
488         x = quotient;
489         // Simple modulo/division approach
490         while (x > 0) {
491           buf[--i] = Character.forDigit((int) (x % radix), radix);
492           x /= radix;
493         }
494       }
495       // Generate string
496       return new String(buf, i, buf.length - i);
497     }
498   }
499 }