001    /*
002     * Copyright (C) 2011 The Guava Authors
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005     * in compliance with the License. You may obtain a copy of the License at
006     * 
007     * http://www.apache.org/licenses/LICENSE-2.0
008     * 
009     * Unless required by applicable law or agreed to in writing, software distributed under the
010     * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
011     * express or implied. See the License for the specific language governing permissions and
012     * limitations under the License.
013     */
014    
015    package com.google.common.primitives;
016    
017    import static com.google.common.base.Preconditions.checkArgument;
018    import static com.google.common.base.Preconditions.checkNotNull;
019    import static com.google.common.primitives.UnsignedInts.INT_MASK;
020    import static com.google.common.primitives.UnsignedInts.compare;
021    import static com.google.common.primitives.UnsignedInts.toLong;
022    
023    import com.google.common.annotations.Beta;
024    import com.google.common.annotations.GwtCompatible;
025    import com.google.common.annotations.GwtIncompatible;
026    
027    import java.math.BigInteger;
028    
029    import javax.annotation.Nullable;
030    
031    /**
032     * A wrapper class for unsigned {@code int} values, supporting arithmetic operations.
033     * 
034     * <p>In some cases, when speed is more important than code readability, it may be faster simply to
035     * treat primitive {@code int} values as unsigned, using the methods from {@link UnsignedInts}.
036     * 
037     * <p>See the Guava User Guide article on <a href=
038     * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
039     * unsigned primitive utilities</a>.
040     * 
041     * @author Louis Wasserman
042     * @since 11.0
043     */
044    @Beta
045    @GwtCompatible(emulated = true)
046    public final class UnsignedInteger extends Number implements Comparable<UnsignedInteger> {
047      public static final UnsignedInteger ZERO = asUnsigned(0);
048      public static final UnsignedInteger ONE = asUnsigned(1);
049      public static final UnsignedInteger MAX_VALUE = asUnsigned(-1);
050    
051      private final int value;
052    
053      private UnsignedInteger(int value) {
054        this.value = value & 0xffffffff;
055      }
056    
057      /**
058       * Returns an {@code UnsignedInteger} that, when treated as signed, is
059       * equal to {@code value}.
060       */
061      public static UnsignedInteger asUnsigned(int value) {
062        return new UnsignedInteger(value);
063      }
064    
065      /**
066       * Returns an {@code UnsignedInteger} that is equal to {@code value},
067       * if possible.  The inverse operation of {@link #longValue()}.
068       */
069      public static UnsignedInteger valueOf(long value) {
070        checkArgument((value & INT_MASK) == value,
071            "value (%s) is outside the range for an unsigned integer value", value);
072        return asUnsigned((int) value);
073      }
074    
075      /**
076       * Returns a {@code UnsignedInteger} representing the same value as the specified
077       * {@link BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}.
078       * 
079       * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^32}
080       */
081      public static UnsignedInteger valueOf(BigInteger value) {
082        checkNotNull(value);
083        checkArgument(value.signum() >= 0 && value.bitLength() <= Integer.SIZE,
084            "value (%s) is outside the range for an unsigned integer value", value);
085        return asUnsigned(value.intValue());
086      }
087    
088      /**
089       * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
090       * as an unsigned {@code int} value.
091       * 
092       * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
093       *         value
094       */
095      public static UnsignedInteger valueOf(String string) {
096        return valueOf(string, 10);
097      }
098    
099      /**
100       * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
101       * as an unsigned {@code int} value in the specified radix.
102       * 
103       * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
104       *         value
105       */
106      public static UnsignedInteger valueOf(String string, int radix) {
107        return asUnsigned(UnsignedInts.parseUnsignedInt(string, radix));
108      }
109    
110      /**
111       * Returns the result of adding this and {@code val}. If the result would have more than 32 bits,
112       * returns the low 32 bits of the result.
113       */
114      public UnsignedInteger add(UnsignedInteger val) {
115        checkNotNull(val);
116        return asUnsigned(this.value + val.value);
117      }
118    
119      /**
120       * Returns the result of subtracting this and {@code val}. If the result would be negative,
121       * returns the low 32 bits of the result.
122       */
123      public UnsignedInteger subtract(UnsignedInteger val) {
124        checkNotNull(val);
125        return asUnsigned(this.value - val.value);
126      }
127    
128      /**
129       * Returns the result of multiplying this and {@code val}. If the result would have more than 32
130       * bits, returns the low 32 bits of the result.
131       */
132      @GwtIncompatible("Does not truncate correctly")
133      public UnsignedInteger multiply(UnsignedInteger val) {
134        checkNotNull(val);
135        return asUnsigned(value * val.value);
136      }
137    
138      /**
139       * Returns the result of dividing this by {@code val}.
140       */
141      public UnsignedInteger divide(UnsignedInteger val) {
142        checkNotNull(val);
143        return asUnsigned(UnsignedInts.divide(value, val.value));
144      }
145    
146      /**
147       * Returns the remainder of dividing this by {@code val}.
148       */
149      public UnsignedInteger remainder(UnsignedInteger val) {
150        checkNotNull(val);
151        return asUnsigned(UnsignedInts.remainder(value, val.value));
152      }
153    
154      /**
155       * Returns the value of this {@code UnsignedInteger} as an {@code int}. This is an inverse
156       * operation to {@link #asUnsigned}.
157       * 
158       * <p>Note that if this {@code UnsignedInteger} holds a value {@code >= 2^31}, the returned value
159       * will be equal to {@code this - 2^32}.
160       */
161      @Override
162      public int intValue() {
163        return value;
164      }
165    
166      /**
167       * Returns the value of this {@code UnsignedInteger} as a {@code long}.
168       */
169      @Override
170      public long longValue() {
171        return toLong(value);
172      }
173    
174      /**
175       * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
176       * primitive conversion from {@code int} to {@code float}, and correctly rounded.
177       */
178      @Override
179      public float floatValue() {
180        return longValue();
181      }
182    
183      /**
184       * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
185       * primitive conversion from {@code int} to {@code double}, and correctly rounded.
186       */
187      @Override
188      public double doubleValue() {
189        return longValue();
190      }
191    
192      /**
193       * Returns the value of this {@code UnsignedInteger} as a {@link BigInteger}.
194       */
195      public BigInteger bigIntegerValue() {
196        return BigInteger.valueOf(longValue());
197      }
198    
199      /**
200       * Compares this unsigned integer to another unsigned integer.
201       * Returns {@code 0} if they are equal, a negative number if {@code this < other},
202       * and a positive number if {@code this > other}.
203       */
204      @Override
205      public int compareTo(UnsignedInteger other) {
206        checkNotNull(other);
207        return compare(value, other.value);
208      }
209    
210      @Override
211      public int hashCode() {
212        return value;
213      }
214    
215      @Override
216      public boolean equals(@Nullable Object obj) {
217        if (obj instanceof UnsignedInteger) {
218          UnsignedInteger other = (UnsignedInteger) obj;
219          return value == other.value;
220        }
221        return false;
222      }
223    
224      /**
225       * Returns a string representation of the {@code UnsignedInteger} value, in base 10.
226       */
227      @Override
228      public String toString() {
229        return toString(10);
230      }
231    
232      /**
233       * Returns a string representation of the {@code UnsignedInteger} value, in base {@code radix}.
234       * If {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix
235       * {@code 10} is used.
236       */
237      public String toString(int radix) {
238        return UnsignedInts.toString(value, radix);
239      }
240    }