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
015package com.google.common.primitives;
016
017import static com.google.common.base.Preconditions.checkArgument;
018import static com.google.common.base.Preconditions.checkNotNull;
019import static com.google.common.primitives.UnsignedInts.INT_MASK;
020import static com.google.common.primitives.UnsignedInts.compare;
021import static com.google.common.primitives.UnsignedInts.toLong;
022
023import com.google.common.annotations.Beta;
024import com.google.common.annotations.GwtCompatible;
025import com.google.common.annotations.GwtIncompatible;
026
027import java.math.BigInteger;
028
029import 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)
046public 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}