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 com.google.common.annotations.Beta; 024 import com.google.common.annotations.GwtCompatible; 025 import com.google.common.annotations.GwtIncompatible; 026 027 import java.math.BigInteger; 028 029 import 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) 046 public 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 }