UnsignedInteger.java revision 1d580d0f6ee4f21eb309ba7b509d2c6d671c4044
1/* 2 * Copyright (C) 2011 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 * express or implied. See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15package com.google.common.primitives; 16 17import static com.google.common.base.Preconditions.checkArgument; 18import static com.google.common.base.Preconditions.checkNotNull; 19import static com.google.common.primitives.UnsignedInts.INT_MASK; 20import static com.google.common.primitives.UnsignedInts.compare; 21import static com.google.common.primitives.UnsignedInts.toLong; 22 23import java.math.BigInteger; 24 25import javax.annotation.Nullable; 26 27import com.google.common.annotations.Beta; 28import com.google.common.annotations.GwtCompatible; 29import com.google.common.annotations.GwtIncompatible; 30 31/** 32 * A wrapper class for unsigned {@code int} values, supporting arithmetic operations. 33 * 34 * <p>In some cases, when speed is more important than code readability, it may be faster simply to 35 * treat primitive {@code int} values as unsigned, using the methods from {@link UnsignedInts}. 36 * 37 * @author Louis Wasserman 38 * @since 11.0 39 */ 40@Beta 41@GwtCompatible(emulated = true) 42public final class UnsignedInteger extends Number implements Comparable<UnsignedInteger> { 43 public static final UnsignedInteger ZERO = asUnsigned(0); 44 public static final UnsignedInteger ONE = asUnsigned(1); 45 public static final UnsignedInteger MAX_VALUE = asUnsigned(-1); 46 47 private final int value; 48 49 private UnsignedInteger(int value) { 50 this.value = value & 0xffffffff; 51 } 52 53 /** 54 * Returns an {@code UnsignedInteger} that, when treated as signed, is 55 * equal to {@code value}. 56 */ 57 public static UnsignedInteger asUnsigned(int value) { 58 return new UnsignedInteger(value); 59 } 60 61 /** 62 * Returns an {@code UnsignedInteger} that is equal to {@code value}, 63 * if possible. The inverse operation of {@link #longValue()}. 64 */ 65 public static UnsignedInteger valueOf(long value) { 66 checkArgument((value & INT_MASK) == value, 67 "value (%s) is outside the range for an unsigned integer value", value); 68 return asUnsigned((int) value); 69 } 70 71 /** 72 * Returns a {@code UnsignedInteger} representing the same value as the specified 73 * {@link BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}. 74 * 75 * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^32} 76 */ 77 public static UnsignedInteger valueOf(BigInteger value) { 78 checkNotNull(value); 79 checkArgument(value.signum() >= 0 && value.bitLength() <= Integer.SIZE, 80 "value (%s) is outside the range for an unsigned integer value", value); 81 return asUnsigned(value.intValue()); 82 } 83 84 /** 85 * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed 86 * as an unsigned {@code int} value. 87 * 88 * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int} 89 * value 90 */ 91 public static UnsignedInteger valueOf(String string) { 92 return valueOf(string, 10); 93 } 94 95 /** 96 * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed 97 * as an unsigned {@code int} value in the specified radix. 98 * 99 * @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} 237