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 java.math.BigInteger;
024    
025    import javax.annotation.Nullable;
026    
027    import com.google.common.annotations.Beta;
028    import com.google.common.annotations.GwtCompatible;
029    import com.google.common.annotations.GwtIncompatible;
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     * @author Louis Wasserman
038     * @since 11.0
039     */
040    @Beta
041    @GwtCompatible(emulated = true)
042    public final class UnsignedInteger extends Number implements Comparable<UnsignedInteger> {
043      public static final UnsignedInteger ZERO = asUnsigned(0);
044      public static final UnsignedInteger ONE = asUnsigned(1);
045      public static final UnsignedInteger MAX_VALUE = asUnsigned(-1);
046    
047      private final int value;
048    
049      private UnsignedInteger(int value) {
050        this.value = value & 0xffffffff;
051      }
052    
053      /**
054       * Returns an {@code UnsignedInteger} that, when treated as signed, is
055       * equal to {@code value}.
056       */
057      public static UnsignedInteger asUnsigned(int value) {
058        return new UnsignedInteger(value);
059      }
060    
061      /**
062       * Returns an {@code UnsignedInteger} that is equal to {@code value},
063       * if possible.  The inverse operation of {@link #longValue()}.
064       */
065      public static UnsignedInteger valueOf(long value) {
066        checkArgument((value & INT_MASK) == value,
067            "value (%s) is outside the range for an unsigned integer value", value);
068        return asUnsigned((int) value);
069      }
070    
071      /**
072       * Returns a {@code UnsignedInteger} representing the same value as the specified
073       * {@link BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}.
074       * 
075       * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^32}
076       */
077      public static UnsignedInteger valueOf(BigInteger value) {
078        checkNotNull(value);
079        checkArgument(value.signum() >= 0 && value.bitLength() <= Integer.SIZE,
080            "value (%s) is outside the range for an unsigned integer value", value);
081        return asUnsigned(value.intValue());
082      }
083    
084      /**
085       * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
086       * as an unsigned {@code int} value.
087       * 
088       * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
089       *         value
090       */
091      public static UnsignedInteger valueOf(String string) {
092        return valueOf(string, 10);
093      }
094    
095      /**
096       * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
097       * as an unsigned {@code int} value in the specified radix.
098       * 
099       * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
100       *         value
101       */
102      public static UnsignedInteger valueOf(String string, int radix) {
103        return asUnsigned(UnsignedInts.parseUnsignedInt(string, radix));
104      }
105    
106      /**
107       * Returns the result of adding this and {@code val}. If the result would have more than 32 bits,
108       * returns the low 32 bits of the result.
109       */
110      public UnsignedInteger add(UnsignedInteger val) {
111        checkNotNull(val);
112        return asUnsigned(this.value + val.value);
113      }
114    
115      /**
116       * Returns the result of subtracting this and {@code val}. If the result would be negative,
117       * returns the low 32 bits of the result.
118       */
119      public UnsignedInteger subtract(UnsignedInteger val) {
120        checkNotNull(val);
121        return asUnsigned(this.value - val.value);
122      }
123    
124      /**
125       * Returns the result of multiplying this and {@code val}. If the result would have more than 32
126       * bits, returns the low 32 bits of the result.
127       */
128      @GwtIncompatible("Does not truncate correctly")
129      public UnsignedInteger multiply(UnsignedInteger val) {
130        checkNotNull(val);
131        return asUnsigned(value * val.value);
132      }
133    
134      /**
135       * Returns the result of dividing this by {@code val}.
136       */
137      public UnsignedInteger divide(UnsignedInteger val) {
138        checkNotNull(val);
139        return asUnsigned(UnsignedInts.divide(value, val.value));
140      }
141    
142      /**
143       * Returns the remainder of dividing this by {@code val}.
144       */
145      public UnsignedInteger remainder(UnsignedInteger val) {
146        checkNotNull(val);
147        return asUnsigned(UnsignedInts.remainder(value, val.value));
148      }
149    
150      /**
151       * Returns the value of this {@code UnsignedInteger} as an {@code int}. This is an inverse
152       * operation to {@link #asUnsigned}.
153       * 
154       * <p>Note that if this {@code UnsignedInteger} holds a value {@code >= 2^31}, the returned value
155       * will be equal to {@code this - 2^32}.
156       */
157      @Override
158      public int intValue() {
159        return value;
160      }
161    
162      /**
163       * Returns the value of this {@code UnsignedInteger} as a {@code long}.
164       */
165      @Override
166      public long longValue() {
167        return toLong(value);
168      }
169    
170      /**
171       * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
172       * primitive conversion from {@code int} to {@code float}, and correctly rounded.
173       */
174      @Override
175      public float floatValue() {
176        return longValue();
177      }
178    
179      /**
180       * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
181       * primitive conversion from {@code int} to {@code double}, and correctly rounded.
182       */
183      @Override
184      public double doubleValue() {
185        return longValue();
186      }
187    
188      /**
189       * Returns the value of this {@code UnsignedInteger} as a {@link BigInteger}.
190       */
191      public BigInteger bigIntegerValue() {
192        return BigInteger.valueOf(longValue());
193      }
194    
195      /**
196       * Compares this unsigned integer to another unsigned integer.
197       * Returns {@code 0} if they are equal, a negative number if {@code this < other},
198       * and a positive number if {@code this > other}.
199       */
200      @Override
201      public int compareTo(UnsignedInteger other) {
202        checkNotNull(other);
203        return compare(value, other.value);
204      }
205    
206      @Override
207      public int hashCode() {
208        return value;
209      }
210    
211      @Override
212      public boolean equals(@Nullable Object obj) {
213        if (obj instanceof UnsignedInteger) {
214          UnsignedInteger other = (UnsignedInteger) obj;
215          return value == other.value;
216        }
217        return false;
218      }
219    
220      /**
221       * Returns a string representation of the {@code UnsignedInteger} value, in base 10.
222       */
223      @Override
224      public String toString() {
225        return toString(10);
226      }
227    
228      /**
229       * Returns a string representation of the {@code UnsignedInteger} value, in base {@code radix}.
230       * If {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix
231       * {@code 10} is used.
232       */
233      public String toString(int radix) {
234        return UnsignedInts.toString(value, radix);
235      }
236    }