Home | History | Annotate | Download | only in primitives
      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.base.Preconditions.checkArgument;
     18 import static com.google.common.base.Preconditions.checkNotNull;
     19 import static com.google.common.primitives.UnsignedInts.INT_MASK;
     20 import static com.google.common.primitives.UnsignedInts.compare;
     21 import static com.google.common.primitives.UnsignedInts.toLong;
     22 
     23 import com.google.common.annotations.GwtCompatible;
     24 
     25 import java.math.BigInteger;
     26 
     27 import javax.annotation.CheckReturnValue;
     28 import javax.annotation.Nullable;
     29 
     30 /**
     31  * A wrapper class for unsigned {@code int} values, supporting arithmetic operations.
     32  *
     33  * <p>In some cases, when speed is more important than code readability, it may be faster simply to
     34  * treat primitive {@code int} values as unsigned, using the methods from {@link UnsignedInts}.
     35  *
     36  * <p>See the Guava User Guide article on <a href=
     37  * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
     38  * unsigned primitive utilities</a>.
     39  *
     40  * @author Louis Wasserman
     41  * @since 11.0
     42  */
     43 @GwtCompatible(emulated = true)
     44 public final class UnsignedInteger extends Number implements Comparable<UnsignedInteger> {
     45   public static final UnsignedInteger ZERO = fromIntBits(0);
     46   public static final UnsignedInteger ONE = fromIntBits(1);
     47   public static final UnsignedInteger MAX_VALUE = fromIntBits(-1);
     48 
     49   private final int value;
     50 
     51   private UnsignedInteger(int value) {
     52     // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
     53     this.value = value & 0xffffffff;
     54   }
     55 
     56   /**
     57    * Returns an {@code UnsignedInteger} corresponding to a given bit representation.
     58    * The argument is interpreted as an unsigned 32-bit value. Specifically, the sign bit
     59    * of {@code bits} is interpreted as a normal bit, and all other bits are treated as usual.
     60    *
     61    * <p>If the argument is nonnegative, the returned result will be equal to {@code bits},
     62    * otherwise, the result will be equal to {@code 2^32 + bits}.
     63    *
     64    * <p>To represent unsigned decimal constants, consider {@link #valueOf(long)} instead.
     65    *
     66    * @since 14.0
     67    */
     68   public static UnsignedInteger fromIntBits(int bits) {
     69     return new UnsignedInteger(bits);
     70   }
     71 
     72   /**
     73    * Returns an {@code UnsignedInteger} that is equal to {@code value},
     74    * if possible.  The inverse operation of {@link #longValue()}.
     75    */
     76   public static UnsignedInteger valueOf(long value) {
     77     checkArgument((value & INT_MASK) == value,
     78         "value (%s) is outside the range for an unsigned integer value", value);
     79     return fromIntBits((int) value);
     80   }
     81 
     82   /**
     83    * Returns a {@code UnsignedInteger} representing the same value as the specified
     84    * {@link BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}.
     85    *
     86    * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^32}
     87    */
     88   public static UnsignedInteger valueOf(BigInteger value) {
     89     checkNotNull(value);
     90     checkArgument(value.signum() >= 0 && value.bitLength() <= Integer.SIZE,
     91         "value (%s) is outside the range for an unsigned integer value", value);
     92     return fromIntBits(value.intValue());
     93   }
     94 
     95   /**
     96    * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
     97    * as an unsigned {@code int} value.
     98    *
     99    * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
    100    *         value
    101    */
    102   public static UnsignedInteger valueOf(String string) {
    103     return valueOf(string, 10);
    104   }
    105 
    106   /**
    107    * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
    108    * as an unsigned {@code int} value in the specified radix.
    109    *
    110    * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
    111    *         value
    112    */
    113   public static UnsignedInteger valueOf(String string, int radix) {
    114     return fromIntBits(UnsignedInts.parseUnsignedInt(string, radix));
    115   }
    116 
    117   /**
    118    * Returns the result of adding this and {@code val}. If the result would have more than 32 bits,
    119    * returns the low 32 bits of the result.
    120    *
    121    * @since 14.0
    122    */
    123   @CheckReturnValue
    124   public UnsignedInteger plus(UnsignedInteger val) {
    125     return fromIntBits(this.value + checkNotNull(val).value);
    126   }
    127 
    128   /**
    129    * Returns the result of subtracting this and {@code val}. If the result would be negative,
    130    * returns the low 32 bits of the result.
    131    *
    132    * @since 14.0
    133    */
    134   @CheckReturnValue
    135   public UnsignedInteger minus(UnsignedInteger val) {
    136     return fromIntBits(value - checkNotNull(val).value);
    137   }
    138 
    139   /**
    140    * Returns the result of dividing this by {@code val}.
    141    *
    142    * @throws ArithmeticException if {@code val} is zero
    143    * @since 14.0
    144    */
    145   @CheckReturnValue
    146   public UnsignedInteger dividedBy(UnsignedInteger val) {
    147     return fromIntBits(UnsignedInts.divide(value, checkNotNull(val).value));
    148   }
    149 
    150   /**
    151    * Returns this mod {@code val}.
    152    *
    153    * @throws ArithmeticException if {@code val} is zero
    154    * @since 14.0
    155    */
    156   @CheckReturnValue
    157   public UnsignedInteger mod(UnsignedInteger val) {
    158     return fromIntBits(UnsignedInts.remainder(value, checkNotNull(val).value));
    159   }
    160 
    161   /**
    162    * Returns the value of this {@code UnsignedInteger} as an {@code int}. This is an inverse
    163    * operation to {@link #fromIntBits}.
    164    *
    165    * <p>Note that if this {@code UnsignedInteger} holds a value {@code >= 2^31}, the returned value
    166    * will be equal to {@code this - 2^32}.
    167    */
    168   @Override
    169   public int intValue() {
    170     return value;
    171   }
    172 
    173   /**
    174    * Returns the value of this {@code UnsignedInteger} as a {@code long}.
    175    */
    176   @Override
    177   public long longValue() {
    178     return toLong(value);
    179   }
    180 
    181   /**
    182    * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
    183    * primitive conversion from {@code int} to {@code float}, and correctly rounded.
    184    */
    185   @Override
    186   public float floatValue() {
    187     return longValue();
    188   }
    189 
    190   /**
    191    * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
    192    * primitive conversion from {@code int} to {@code double}, and correctly rounded.
    193    */
    194   @Override
    195   public double doubleValue() {
    196     return longValue();
    197   }
    198 
    199   /**
    200    * Returns the value of this {@code UnsignedInteger} as a {@link BigInteger}.
    201    */
    202   public BigInteger bigIntegerValue() {
    203     return BigInteger.valueOf(longValue());
    204   }
    205 
    206   /**
    207    * Compares this unsigned integer to another unsigned integer.
    208    * Returns {@code 0} if they are equal, a negative number if {@code this < other},
    209    * and a positive number if {@code this > other}.
    210    */
    211   @Override
    212   public int compareTo(UnsignedInteger other) {
    213     checkNotNull(other);
    214     return compare(value, other.value);
    215   }
    216 
    217   @Override
    218   public int hashCode() {
    219     return value;
    220   }
    221 
    222   @Override
    223   public boolean equals(@Nullable Object obj) {
    224     if (obj instanceof UnsignedInteger) {
    225       UnsignedInteger other = (UnsignedInteger) obj;
    226       return value == other.value;
    227     }
    228     return false;
    229   }
    230 
    231   /**
    232    * Returns a string representation of the {@code UnsignedInteger} value, in base 10.
    233    */
    234   @Override
    235   public String toString() {
    236     return toString(10);
    237   }
    238 
    239   /**
    240    * Returns a string representation of the {@code UnsignedInteger} value, in base {@code radix}.
    241    * If {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix
    242    * {@code 10} is used.
    243    */
    244   public String toString(int radix) {
    245     return UnsignedInts.toString(value, radix);
    246   }
    247 }
    248 
    249