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}