Coverage Summary for Class: UnsignedLong (com.google.common.primitives)

Class Class, % Method, % Line, %
UnsignedLong 100% (1/1) 27.3% (6/22) 31.7% (13/41)


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 License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.primitives; 16  17 import static com.google.common.base.Preconditions.checkArgument; 18 import static com.google.common.base.Preconditions.checkNotNull; 19  20 import com.google.common.annotations.GwtCompatible; 21 import com.google.errorprone.annotations.CanIgnoreReturnValue; 22 import java.io.Serializable; 23 import java.math.BigInteger; 24 import javax.annotation.CheckForNull; 25  26 /** 27  * A wrapper class for unsigned {@code long} values, supporting arithmetic operations. 28  * 29  * <p>In some cases, when speed is more important than code readability, it may be faster simply to 30  * treat primitive {@code long} values as unsigned, using the methods from {@link UnsignedLongs}. 31  * 32  * <p>See the Guava User Guide article on <a 33  * href="https://github.com/google/guava/wiki/PrimitivesExplained#unsigned-support">unsigned 34  * primitive utilities</a>. 35  * 36  * @author Louis Wasserman 37  * @author Colin Evans 38  * @since 11.0 39  */ 40 @GwtCompatible(serializable = true) 41 @ElementTypesAreNonnullByDefault 42 public final class UnsignedLong extends Number implements Comparable<UnsignedLong>, Serializable { 43  44  private static final long UNSIGNED_MASK = 0x7fffffffffffffffL; 45  46  public static final UnsignedLong ZERO = new UnsignedLong(0); 47  public static final UnsignedLong ONE = new UnsignedLong(1); 48  public static final UnsignedLong MAX_VALUE = new UnsignedLong(-1L); 49  50  private final long value; 51  52  private UnsignedLong(long value) { 53  this.value = value; 54  } 55  56  /** 57  * Returns an {@code UnsignedLong} corresponding to a given bit representation. The argument is 58  * interpreted as an unsigned 64-bit value. Specifically, the sign bit of {@code bits} is 59  * interpreted as a normal bit, and all other bits are treated as usual. 60  * 61  * <p>If the argument is nonnegative, the returned result will be equal to {@code bits}, 62  * otherwise, the result will be equal to {@code 2^64 + bits}. 63  * 64  * <p>To represent decimal constants less than {@code 2^63}, consider {@link #valueOf(long)} 65  * instead. 66  * 67  * @since 14.0 68  */ 69  public static UnsignedLong fromLongBits(long bits) { 70  // TODO(lowasser): consider caching small values, like Long.valueOf 71  return new UnsignedLong(bits); 72  } 73  74  /** 75  * Returns an {@code UnsignedLong} representing the same value as the specified {@code long}. 76  * 77  * @throws IllegalArgumentException if {@code value} is negative 78  * @since 14.0 79  */ 80  @CanIgnoreReturnValue 81  public static UnsignedLong valueOf(long value) { 82  checkArgument(value >= 0, "value (%s) is outside the range for an unsigned long value", value); 83  return fromLongBits(value); 84  } 85  86  /** 87  * Returns a {@code UnsignedLong} representing the same value as the specified {@code BigInteger}. 88  * This is the inverse operation of {@link #bigIntegerValue()}. 89  * 90  * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^64} 91  */ 92  @CanIgnoreReturnValue 93  public static UnsignedLong valueOf(BigInteger value) { 94  checkNotNull(value); 95  checkArgument( 96  value.signum() >= 0 && value.bitLength() <= Long.SIZE, 97  "value (%s) is outside the range for an unsigned long value", 98  value); 99  return fromLongBits(value.longValue()); 100  } 101  102  /** 103  * Returns an {@code UnsignedLong} holding the value of the specified {@code String}, parsed as an 104  * unsigned {@code long} value. 105  * 106  * @throws NumberFormatException if the string does not contain a parsable unsigned {@code long} 107  * value 108  */ 109  @CanIgnoreReturnValue 110  public static UnsignedLong valueOf(String string) { 111  return valueOf(string, 10); 112  } 113  114  /** 115  * Returns an {@code UnsignedLong} holding the value of the specified {@code String}, parsed as an 116  * unsigned {@code long} value in the specified radix. 117  * 118  * @throws NumberFormatException if the string does not contain a parsable unsigned {@code long} 119  * value, or {@code radix} is not between {@link Character#MIN_RADIX} and {@link 120  * Character#MAX_RADIX} 121  */ 122  @CanIgnoreReturnValue 123  public static UnsignedLong valueOf(String string, int radix) { 124  return fromLongBits(UnsignedLongs.parseUnsignedLong(string, radix)); 125  } 126  127  /** 128  * Returns the result of adding this and {@code val}. If the result would have more than 64 bits, 129  * returns the low 64 bits of the result. 130  * 131  * @since 14.0 132  */ 133  public UnsignedLong plus(UnsignedLong val) { 134  return fromLongBits(this.value + checkNotNull(val).value); 135  } 136  137  /** 138  * Returns the result of subtracting this and {@code val}. If the result would have more than 64 139  * bits, returns the low 64 bits of the result. 140  * 141  * @since 14.0 142  */ 143  public UnsignedLong minus(UnsignedLong val) { 144  return fromLongBits(this.value - checkNotNull(val).value); 145  } 146  147  /** 148  * Returns the result of multiplying this and {@code val}. If the result would have more than 64 149  * bits, returns the low 64 bits of the result. 150  * 151  * @since 14.0 152  */ 153  public UnsignedLong times(UnsignedLong val) { 154  return fromLongBits(value * checkNotNull(val).value); 155  } 156  157  /** 158  * Returns the result of dividing this by {@code val}. 159  * 160  * @since 14.0 161  */ 162  public UnsignedLong dividedBy(UnsignedLong val) { 163  return fromLongBits(UnsignedLongs.divide(value, checkNotNull(val).value)); 164  } 165  166  /** 167  * Returns this modulo {@code val}. 168  * 169  * @since 14.0 170  */ 171  public UnsignedLong mod(UnsignedLong val) { 172  return fromLongBits(UnsignedLongs.remainder(value, checkNotNull(val).value)); 173  } 174  175  /** Returns the value of this {@code UnsignedLong} as an {@code int}. */ 176  @Override 177  public int intValue() { 178  return (int) value; 179  } 180  181  /** 182  * Returns the value of this {@code UnsignedLong} as a {@code long}. This is an inverse operation 183  * to {@link #fromLongBits}. 184  * 185  * <p>Note that if this {@code UnsignedLong} holds a value {@code >= 2^63}, the returned value 186  * will be equal to {@code this - 2^64}. 187  */ 188  @Override 189  public long longValue() { 190  return value; 191  } 192  193  /** 194  * Returns the value of this {@code UnsignedLong} as a {@code float}, analogous to a widening 195  * primitive conversion from {@code long} to {@code float}, and correctly rounded. 196  */ 197  @Override 198  public float floatValue() { 199  if (value >= 0) { 200  return (float) value; 201  } 202  // The top bit is set, which means that the float value is going to come from the top 24 bits. 203  // So we can ignore the bottom 8, except for rounding. See doubleValue() for more. 204  return (float) ((value >>> 1) | (value & 1)) * 2f; 205  } 206  207  /** 208  * Returns the value of this {@code UnsignedLong} as a {@code double}, analogous to a widening 209  * primitive conversion from {@code long} to {@code double}, and correctly rounded. 210  */ 211  @Override 212  public double doubleValue() { 213  if (value >= 0) { 214  return (double) value; 215  } 216  // The top bit is set, which means that the double value is going to come from the top 53 bits. 217  // So we can ignore the bottom 11, except for rounding. We can unsigned-shift right 1, aka 218  // unsigned-divide by 2, and convert that. Then we'll get exactly half of the desired double 219  // value. But in the specific case where the bottom two bits of the original number are 01, we 220  // want to replace that with 1 in the shifted value for correct rounding. 221  return (double) ((value >>> 1) | (value & 1)) * 2.0; 222  } 223  224  /** Returns the value of this {@code UnsignedLong} as a {@link BigInteger}. */ 225  public BigInteger bigIntegerValue() { 226  BigInteger bigInt = BigInteger.valueOf(value & UNSIGNED_MASK); 227  if (value < 0) { 228  bigInt = bigInt.setBit(Long.SIZE - 1); 229  } 230  return bigInt; 231  } 232  233  @Override 234  public int compareTo(UnsignedLong o) { 235  checkNotNull(o); 236  return UnsignedLongs.compare(value, o.value); 237  } 238  239  @Override 240  public int hashCode() { 241  return Longs.hashCode(value); 242  } 243  244  @Override 245  public boolean equals(@CheckForNull Object obj) { 246  if (obj instanceof UnsignedLong) { 247  UnsignedLong other = (UnsignedLong) obj; 248  return value == other.value; 249  } 250  return false; 251  } 252  253  /** Returns a string representation of the {@code UnsignedLong} value, in base 10. */ 254  @Override 255  public String toString() { 256  return UnsignedLongs.toString(value); 257  } 258  259  /** 260  * Returns a string representation of the {@code UnsignedLong} value, in base {@code radix}. If 261  * {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix {@code 262  * 10} is used. 263  */ 264  public String toString(int radix) { 265  return UnsignedLongs.toString(value, radix); 266  } 267 }