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 }