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.CheckReturnValue; 030import javax.annotation.Nullable; 031 032/** 033 * A wrapper class for unsigned {@code int} values, supporting arithmetic operations. 034 * 035 * <p>In some cases, when speed is more important than code readability, it may be faster simply to 036 * treat primitive {@code int} values as unsigned, using the methods from {@link UnsignedInts}. 037 * 038 * <p>See the Guava User Guide article on <a href= 039 * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support"> 040 * unsigned primitive utilities</a>. 041 * 042 * @author Louis Wasserman 043 * @since 11.0 044 */ 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 // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it. 055 this.value = value & 0xffffffff; 056 } 057 058 /** 059 * Returns an {@code UnsignedInteger} that, when treated as signed, is 060 * equal to {@code value}. 061 * 062 * @deprecated Use {@link #fromIntBits(int)}. This method is scheduled to be removed in Guava 063 * release 15.0. 064 */ 065 @Deprecated 066 @Beta 067 public static UnsignedInteger asUnsigned(int value) { 068 return fromIntBits(value); 069 } 070 071 /** 072 * Returns an {@code UnsignedInteger} corresponding to a given bit representation. 073 * The argument is interpreted as an unsigned 32-bit value. Specifically, the sign bit 074 * of {@code bits} is interpreted as a normal bit, and all other bits are treated as usual. 075 * 076 * <p>If the argument is nonnegative, the returned result will be equal to {@code bits}, 077 * otherwise, the result will be equal to {@code 2^32 + bits}. 078 * 079 * <p>To represent unsigned decimal constants, consider {@link #valueOf(long)} instead. 080 * 081 * @since 14.0 082 */ 083 public static UnsignedInteger fromIntBits(int bits) { 084 return new UnsignedInteger(bits); 085 } 086 087 /** 088 * Returns an {@code UnsignedInteger} that is equal to {@code value}, 089 * if possible. The inverse operation of {@link #longValue()}. 090 */ 091 public static UnsignedInteger valueOf(long value) { 092 checkArgument((value & INT_MASK) == value, 093 "value (%s) is outside the range for an unsigned integer value", value); 094 return fromIntBits((int) value); 095 } 096 097 /** 098 * Returns a {@code UnsignedInteger} representing the same value as the specified 099 * {@link BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}. 100 * 101 * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^32} 102 */ 103 public static UnsignedInteger valueOf(BigInteger value) { 104 checkNotNull(value); 105 checkArgument(value.signum() >= 0 && value.bitLength() <= Integer.SIZE, 106 "value (%s) is outside the range for an unsigned integer value", value); 107 return fromIntBits(value.intValue()); 108 } 109 110 /** 111 * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed 112 * as an unsigned {@code int} value. 113 * 114 * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int} 115 * value 116 */ 117 public static UnsignedInteger valueOf(String string) { 118 return valueOf(string, 10); 119 } 120 121 /** 122 * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed 123 * as an unsigned {@code int} value in the specified radix. 124 * 125 * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int} 126 * value 127 */ 128 public static UnsignedInteger valueOf(String string, int radix) { 129 return fromIntBits(UnsignedInts.parseUnsignedInt(string, radix)); 130 } 131 132 /** 133 * Returns the result of adding this and {@code val}. If the result would have more than 32 bits, 134 * returns the low 32 bits of the result. 135 * 136 * @deprecated Use {@link #plus(UnsignedInteger)}. This method is scheduled to be removed in Guava 137 * release 15.0. 138 */ 139 @Deprecated 140 @Beta 141 public UnsignedInteger add(UnsignedInteger val) { 142 return plus(val); 143 } 144 145 /** 146 * Returns the result of adding this and {@code val}. If the result would have more than 32 bits, 147 * returns the low 32 bits of the result. 148 * 149 * @since 14.0 150 */ 151 @CheckReturnValue 152 public UnsignedInteger plus(UnsignedInteger val) { 153 return fromIntBits(this.value + checkNotNull(val).value); 154 } 155 156 /** 157 * Returns the result of subtracting this and {@code val}. If the result would be negative, 158 * returns the low 32 bits of the result. 159 * 160 * @deprecated Use {@link #minus(UnsignedInteger)}. This method is scheduled to be removed in 161 * Guava release 15.0. 162 */ 163 @Deprecated 164 @Beta 165 public UnsignedInteger subtract(UnsignedInteger val) { 166 return minus(val); 167 } 168 169 /** 170 * Returns the result of subtracting this and {@code val}. If the result would be negative, 171 * returns the low 32 bits of the result. 172 * 173 * @since 14.0 174 */ 175 @CheckReturnValue 176 public UnsignedInteger minus(UnsignedInteger val) { 177 return fromIntBits(value - checkNotNull(val).value); 178 } 179 180 /** 181 * Returns the result of multiplying this and {@code val}. If the result would have more than 32 182 * bits, returns the low 32 bits of the result. 183 * 184 * @deprecated Use {@link #times(UnsignedInteger)}. This method is scheduled to be removed in 185 * Guava release 15.0. 186 */ 187 @Deprecated 188 @Beta 189 @GwtIncompatible("Does not truncate correctly") 190 public UnsignedInteger multiply(UnsignedInteger val) { 191 return times(val); 192 } 193 194 /** 195 * Returns the result of multiplying this and {@code val}. If the result would have more than 32 196 * bits, returns the low 32 bits of the result. 197 * 198 * @since 14.0 199 */ 200 @CheckReturnValue 201 @GwtIncompatible("Does not truncate correctly") 202 public UnsignedInteger times(UnsignedInteger val) { 203 // TODO(user): make this GWT-compatible 204 return fromIntBits(value * checkNotNull(val).value); 205 } 206 207 /** 208 * Returns the result of dividing this by {@code val}. 209 * 210 * @deprecated Use {@link #dividedBy(UnsignedInteger)}. This method is scheduled to be removed in 211 * Guava release 15.0. 212 */ 213 @Deprecated 214 @Beta 215 public UnsignedInteger divide(UnsignedInteger val) { 216 return dividedBy(val); 217 } 218 219 /** 220 * Returns the result of dividing this by {@code val}. 221 * 222 * @throws ArithmeticException if {@code val} is zero 223 * @since 14.0 224 */ 225 @CheckReturnValue 226 public UnsignedInteger dividedBy(UnsignedInteger val) { 227 return fromIntBits(UnsignedInts.divide(value, checkNotNull(val).value)); 228 } 229 230 /** 231 * Returns the remainder of dividing this by {@code val}. 232 * 233 * @deprecated Use {@link #mod(UnsignedInteger)}. This method is scheduled to be removed in Guava 234 * release 15.0. 235 */ 236 @Deprecated 237 @Beta 238 public UnsignedInteger remainder(UnsignedInteger val) { 239 return mod(val); 240 } 241 242 /** 243 * Returns this mod {@code val}. 244 * 245 * @throws ArithmeticException if {@code val} is zero 246 * @since 14.0 247 */ 248 @CheckReturnValue 249 public UnsignedInteger mod(UnsignedInteger val) { 250 return fromIntBits(UnsignedInts.remainder(value, checkNotNull(val).value)); 251 } 252 253 /** 254 * Returns the value of this {@code UnsignedInteger} as an {@code int}. This is an inverse 255 * operation to {@link #fromIntBits}. 256 * 257 * <p>Note that if this {@code UnsignedInteger} holds a value {@code >= 2^31}, the returned value 258 * will be equal to {@code this - 2^32}. 259 */ 260 @Override 261 public int intValue() { 262 return value; 263 } 264 265 /** 266 * Returns the value of this {@code UnsignedInteger} as a {@code long}. 267 */ 268 @Override 269 public long longValue() { 270 return toLong(value); 271 } 272 273 /** 274 * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening 275 * primitive conversion from {@code int} to {@code float}, and correctly rounded. 276 */ 277 @Override 278 public float floatValue() { 279 return longValue(); 280 } 281 282 /** 283 * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening 284 * primitive conversion from {@code int} to {@code double}, and correctly rounded. 285 */ 286 @Override 287 public double doubleValue() { 288 return longValue(); 289 } 290 291 /** 292 * Returns the value of this {@code UnsignedInteger} as a {@link BigInteger}. 293 */ 294 public BigInteger bigIntegerValue() { 295 return BigInteger.valueOf(longValue()); 296 } 297 298 /** 299 * Compares this unsigned integer to another unsigned integer. 300 * Returns {@code 0} if they are equal, a negative number if {@code this < other}, 301 * and a positive number if {@code this > other}. 302 */ 303 @Override 304 public int compareTo(UnsignedInteger other) { 305 checkNotNull(other); 306 return compare(value, other.value); 307 } 308 309 @Override 310 public int hashCode() { 311 return value; 312 } 313 314 @Override 315 public boolean equals(@Nullable Object obj) { 316 if (obj instanceof UnsignedInteger) { 317 UnsignedInteger other = (UnsignedInteger) obj; 318 return value == other.value; 319 } 320 return false; 321 } 322 323 /** 324 * Returns a string representation of the {@code UnsignedInteger} value, in base 10. 325 */ 326 @Override 327 public String toString() { 328 return toString(10); 329 } 330 331 /** 332 * Returns a string representation of the {@code UnsignedInteger} value, in base {@code radix}. 333 * If {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix 334 * {@code 10} is used. 335 */ 336 public String toString(int radix) { 337 return UnsignedInts.toString(value, radix); 338 } 339}