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      
162      @Override
163      public int intValue() {
164        return value;
165      }
166    
167      /**
168       * Returns the value of this {@code UnsignedInteger} as a {@code long}.
169       */
170      
171      @Override
172      public long longValue() {
173        return toLong(value);
174      }
175    
176      /**
177       * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
178       * primitive conversion from {@code int} to {@code float}, and correctly rounded.
179       */
180      
181      @Override
182      public float floatValue() {
183        return longValue();
184      }
185    
186      /**
187       * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
188       * primitive conversion from {@code int} to {@code double}, and correctly rounded.
189       */
190      
191      @Override
192      public double doubleValue() {
193        return longValue();
194      }
195    
196      /**
197       * Returns the value of this {@code UnsignedInteger} as a {@link BigInteger}.
198       */
199      public BigInteger bigIntegerValue() {
200        return BigInteger.valueOf(longValue());
201      }
202    
203      /**
204       * Compares this unsigned integer to another unsigned integer.
205       * Returns {@code 0} if they are equal, a negative number if {@code this < other},
206       * and a positive number if {@code this > other}.
207       */
208      public int compareTo(UnsignedInteger other) {
209        checkNotNull(other);
210        return compare(value, other.value);
211      }
212    
213      
214      @Override
215      public int hashCode() {
216        return value;
217      }
218    
219      
220      @Override
221      public boolean equals(@Nullable Object obj) {
222        if (obj instanceof UnsignedInteger) {
223          UnsignedInteger other = (UnsignedInteger) obj;
224          return value == other.value;
225        }
226        return false;
227      }
228    
229      /**
230       * Returns a string representation of the {@code UnsignedInteger} value, in base 10.
231       */
232      
233      @Override
234      public String toString() {
235        return toString(10);
236      }
237    
238      /**
239       * Returns a string representation of the {@code UnsignedInteger} value, in base {@code radix}.
240       * If {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix
241       * {@code 10} is used.
242       */
243      public String toString(int radix) {
244        return UnsignedInts.toString(value, radix);
245      }
246    }