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 }