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 License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * 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; 019 020import com.google.common.annotations.GwtCompatible; 021import com.google.common.annotations.GwtIncompatible; 022import com.google.common.annotations.J2ktIncompatible; 023import com.google.errorprone.annotations.CanIgnoreReturnValue; 024import java.math.BigInteger; 025import org.jspecify.annotations.Nullable; 026 027/** 028 * A wrapper class for unsigned {@code long} values, supporting arithmetic operations. 029 * 030 * <p>In some cases, when speed is more important than code readability, it may be faster simply to 031 * treat primitive {@code long} values as unsigned, using the methods from {@link UnsignedLongs}. 032 * 033 * <p>See the Guava User Guide article on <a 034 * href="https://github.com/google/guava/wiki/PrimitivesExplained#unsigned-support">unsigned 035 * primitive utilities</a>. 036 * 037 * @author Louis Wasserman 038 * @author Colin Evans 039 * @since 11.0 040 */ 041@GwtCompatible 042public final class UnsignedLong extends Number implements Comparable<UnsignedLong> { 043 044 private static final long UNSIGNED_MASK = 0x7fffffffffffffffL; 045 046 /** An {@code UnsignedLong} constant holding the value 0. */ 047 public static final UnsignedLong ZERO = new UnsignedLong(0); 048 049 /** An {@code UnsignedLong} constant holding the value 1. */ 050 public static final UnsignedLong ONE = new UnsignedLong(1); 051 052 /** An {@code UnsignedLong} constant holding the maximum value, 2^64 - 1. */ 053 public static final UnsignedLong MAX_VALUE = new UnsignedLong(-1L); 054 055 private final long value; 056 057 private UnsignedLong(long value) { 058 this.value = value; 059 } 060 061 /** 062 * Returns an {@code UnsignedLong} corresponding to a given bit representation. The argument is 063 * interpreted as an unsigned 64-bit value. Specifically, the sign bit of {@code bits} is 064 * interpreted as a normal bit, and all other bits are treated as usual. 065 * 066 * <p>If the argument is nonnegative, the returned result will be equal to {@code bits}, 067 * otherwise, the result will be equal to {@code 2^64 + bits}. 068 * 069 * <p>To represent decimal constants less than {@code 2^63}, consider {@link #valueOf(long)} 070 * instead. 071 * 072 * @since 14.0 073 */ 074 public static UnsignedLong fromLongBits(long bits) { 075 // TODO(lowasser): consider caching small values, like Long.valueOf 076 return new UnsignedLong(bits); 077 } 078 079 /** 080 * Returns an {@code UnsignedLong} representing the same value as the specified {@code long}. 081 * 082 * @throws IllegalArgumentException if {@code value} is negative 083 * @since 14.0 084 */ 085 @CanIgnoreReturnValue 086 public static UnsignedLong valueOf(long value) { 087 checkArgument(value >= 0, "value (%s) is outside the range for an unsigned long value", value); 088 return fromLongBits(value); 089 } 090 091 /** 092 * Returns a {@code UnsignedLong} representing the same value as the specified {@code BigInteger}. 093 * This is the inverse operation of {@link #bigIntegerValue()}. 094 * 095 * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^64} 096 */ 097 @CanIgnoreReturnValue 098 public static UnsignedLong valueOf(BigInteger value) { 099 checkNotNull(value); 100 checkArgument( 101 value.signum() >= 0 && value.bitLength() <= Long.SIZE, 102 "value (%s) is outside the range for an unsigned long value", 103 value); 104 return fromLongBits(value.longValue()); 105 } 106 107 /** 108 * Returns an {@code UnsignedLong} holding the value of the specified {@code String}, parsed as an 109 * unsigned {@code long} value. 110 * 111 * @throws NumberFormatException if the string does not contain a parsable unsigned {@code long} 112 * value 113 */ 114 @CanIgnoreReturnValue 115 public static UnsignedLong valueOf(String string) { 116 return valueOf(string, 10); 117 } 118 119 /** 120 * Returns an {@code UnsignedLong} holding the value of the specified {@code String}, parsed as an 121 * unsigned {@code long} value in the specified radix. 122 * 123 * @throws NumberFormatException if the string does not contain a parsable unsigned {@code long} 124 * value, or {@code radix} is not between {@link Character#MIN_RADIX} and {@link 125 * Character#MAX_RADIX} 126 */ 127 @CanIgnoreReturnValue 128 public static UnsignedLong valueOf(String string, int radix) { 129 return fromLongBits(UnsignedLongs.parseUnsignedLong(string, radix)); 130 } 131 132 /** 133 * Returns the result of adding this and {@code val}. If the result would have more than 64 bits, 134 * returns the low 64 bits of the result. 135 * 136 * @since 14.0 137 */ 138 public UnsignedLong plus(UnsignedLong val) { 139 return fromLongBits(this.value + checkNotNull(val).value); 140 } 141 142 /** 143 * Returns the result of subtracting this and {@code val}. If the result would have more than 64 144 * bits, returns the low 64 bits of the result. 145 * 146 * @since 14.0 147 */ 148 public UnsignedLong minus(UnsignedLong val) { 149 return fromLongBits(this.value - checkNotNull(val).value); 150 } 151 152 /** 153 * Returns the result of multiplying this and {@code val}. If the result would have more than 64 154 * bits, returns the low 64 bits of the result. 155 * 156 * @since 14.0 157 */ 158 public UnsignedLong times(UnsignedLong val) { 159 return fromLongBits(value * checkNotNull(val).value); 160 } 161 162 /** 163 * Returns the result of dividing this by {@code val}. 164 * 165 * @since 14.0 166 */ 167 public UnsignedLong dividedBy(UnsignedLong val) { 168 return fromLongBits(UnsignedLongs.divide(value, checkNotNull(val).value)); 169 } 170 171 /** 172 * Returns this modulo {@code val}. 173 * 174 * @since 14.0 175 */ 176 public UnsignedLong mod(UnsignedLong val) { 177 return fromLongBits(UnsignedLongs.remainder(value, checkNotNull(val).value)); 178 } 179 180 /** Returns the value of this {@code UnsignedLong} as an {@code int}. */ 181 @Override 182 public int intValue() { 183 return (int) value; 184 } 185 186 /** 187 * Returns the value of this {@code UnsignedLong} as a {@code long}. This is an inverse operation 188 * to {@link #fromLongBits}. 189 * 190 * <p>Note that if this {@code UnsignedLong} holds a value {@code >= 2^63}, the returned value 191 * will be equal to {@code this - 2^64}. 192 */ 193 @Override 194 public long longValue() { 195 return value; 196 } 197 198 /** 199 * Returns the value of this {@code UnsignedLong} as a {@code float}, analogous to a widening 200 * primitive conversion from {@code long} to {@code float}, and correctly rounded. 201 */ 202 @Override 203 public float floatValue() { 204 if (value >= 0) { 205 return (float) value; 206 } 207 // The top bit is set, which means that the float value is going to come from the top 24 bits. 208 // So we can ignore the bottom 8, except for rounding. See doubleValue() for more. 209 return (float) ((value >>> 1) | (value & 1)) * 2f; 210 } 211 212 /** 213 * Returns the value of this {@code UnsignedLong} as a {@code double}, analogous to a widening 214 * primitive conversion from {@code long} to {@code double}, and correctly rounded. 215 */ 216 @Override 217 public double doubleValue() { 218 if (value >= 0) { 219 return (double) value; 220 } 221 // The top bit is set, which means that the double value is going to come from the top 53 bits. 222 // So we can ignore the bottom 11, except for rounding. We can unsigned-shift right 1, aka 223 // unsigned-divide by 2, and convert that. Then we'll get exactly half of the desired double 224 // value. But in the specific case where the bottom two bits of the original number are 01, we 225 // want to replace that with 1 in the shifted value for correct rounding. 226 return (double) ((value >>> 1) | (value & 1)) * 2.0; 227 } 228 229 /** Returns the value of this {@code UnsignedLong} as a {@link BigInteger}. */ 230 public BigInteger bigIntegerValue() { 231 BigInteger bigInt = BigInteger.valueOf(value & UNSIGNED_MASK); 232 if (value < 0) { 233 bigInt = bigInt.setBit(Long.SIZE - 1); 234 } 235 return bigInt; 236 } 237 238 @Override 239 public int compareTo(UnsignedLong o) { 240 checkNotNull(o); 241 return UnsignedLongs.compare(value, o.value); 242 } 243 244 @Override 245 public int hashCode() { 246 return Long.hashCode(value); 247 } 248 249 @Override 250 public boolean equals(@Nullable Object obj) { 251 if (obj instanceof UnsignedLong) { 252 UnsignedLong other = (UnsignedLong) obj; 253 return value == other.value; 254 } 255 return false; 256 } 257 258 /** Returns a string representation of the {@code UnsignedLong} value, in base 10. */ 259 @Override 260 public String toString() { 261 return UnsignedLongs.toString(value); 262 } 263 264 /** 265 * Returns a string representation of the {@code UnsignedLong} value, in base {@code radix}. If 266 * {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix {@code 267 * 10} is used. 268 */ 269 public String toString(int radix) { 270 return UnsignedLongs.toString(value, radix); 271 } 272 273 @GwtIncompatible @J2ktIncompatible private static final long serialVersionUID = 389107927943716141L; 274}