    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
    020    import com.google.common.annotations.Beta;
    021    import com.google.common.annotations.GwtCompatible;
    022
    023    import java.io.Serializable;
    024    import java.math.BigInteger;
    025
    026    import javax.annotation.Nullable;
    027
    028    /**
    029     * A wrapper class for unsigned {@code long} values, supporting arithmetic operations.
    030     *
    031     * <p>In some cases, when speed is more important than code readability, it may be faster simply to
    032     * treat primitive {@code long} values as unsigned, using the methods from {@link UnsignedLongs}.
    033     *
    034     * <p>See the Guava User Guide article on <a href=
    035     * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
    036     * unsigned primitive utilities</a>.
    037     *
    038     * @author Louis Wasserman
    039     * @author Colin Evans
    040     * @since 11.0
    041     */
    042    @Beta
    043    @GwtCompatible(serializable = true)
    044    public final class UnsignedLong extends Number implements Comparable<UnsignedLong>, Serializable {
    045
    046      private static final long UNSIGNED_MASK = 0x7fffffffffffffffL;
    047
    048      public static final UnsignedLong ZERO = new UnsignedLong(0);
    049      public static final UnsignedLong ONE = new UnsignedLong(1);
    050      public static final UnsignedLong MAX_VALUE = new UnsignedLong(-1L);
    051
    052      private final long value;
    053
    054      private UnsignedLong(long value) {
    055        this.value = value;
    056      }
    057
    058      /**
    059       * Returns an {@code UnsignedLong} that, when treated as signed, is equal to {@code value}. The
    060       * inverse operation is {@link #longValue()}.
    061       *
    062       * <p>Put another way, if {@code value} is negative, the returned result will be equal to
    063       * {@code 2^64 + value}; otherwise, the returned result will be equal to {@code value}.
    064       */
    065      public static UnsignedLong asUnsigned(long value) {
    066        return new UnsignedLong(value);
    067      }
    068
    069      /**
    070       * Returns a {@code UnsignedLong} representing the same value as the specified {@code BigInteger}
    071       * . This is the inverse operation of {@link #bigIntegerValue()}.
    072       *
    073       * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^64}
    074       */
    075      public static UnsignedLong valueOf(BigInteger value) {
    076        checkNotNull(value);
    077        checkArgument(value.signum() >= 0 && value.bitLength() <= Long.SIZE,
    078            "value (%s) is outside the range for an unsigned long value", value);
    079        return asUnsigned(value.longValue());
    080      }
    081
    082      /**
    083       * Returns an {@code UnsignedLong} holding the value of the specified {@code String}, parsed as
    084       * an unsigned {@code long} value.
    085       *
    086       * @throws NumberFormatException if the string does not contain a parsable unsigned {@code long}
    087       *         value
    088       */
    089      public static UnsignedLong valueOf(String string) {
    090        return valueOf(string, 10);
    091      }
    092
    093      /**
    094       * Returns an {@code UnsignedLong} holding the value of the specified {@code String}, parsed as
    095       * an unsigned {@code long} value in the specified radix.
    096       *
    097       * @throws NumberFormatException if the string does not contain a parsable unsigned {@code long}
    098       *         value, or {@code radix} is not between {@link Character#MIN_RADIX} and
    099       *         {@link Character#MAX_RADIX}
    100       */
    101      public static UnsignedLong valueOf(String string, int radix) {
    102        return asUnsigned(UnsignedLongs.parseUnsignedLong(string, radix));
    103      }
    104
    105      /**
    106       * Returns the result of adding this and {@code val}. If the result would have more than 64 bits,
    107       * returns the low 64 bits of the result.
    108       */
    109      public UnsignedLong add(UnsignedLong val) {
    110        checkNotNull(val);
    111        return asUnsigned(this.value + val.value);
    112      }
    113
    114      /**
    115       * Returns the result of subtracting this and {@code val}. If the result would be negative,
    116       * returns the low 64 bits of the result.
    117       */
    118      public UnsignedLong subtract(UnsignedLong val) {
    119        checkNotNull(val);
    120        return asUnsigned(this.value - val.value);
    121      }
    122
    123      /**
    124       * Returns the result of multiplying this and {@code val}. If the result would have more than 64
    125       * bits, returns the low 64 bits of the result.
    126       */
    127      public UnsignedLong multiply(UnsignedLong val) {
    128        checkNotNull(val);
    129        return asUnsigned(value * val.value);
    130      }
    131
    132      /**
    133       * Returns the result of dividing this by {@code val}.
    134       */
    135      public UnsignedLong divide(UnsignedLong val) {
    136        checkNotNull(val);
    137        return asUnsigned(UnsignedLongs.divide(value, val.value));
    138      }
    139
    140      /**
    141       * Returns the remainder of dividing this by {@code val}.
    142       */
    143      public UnsignedLong remainder(UnsignedLong val) {
    144        checkNotNull(val);
    145        return asUnsigned(UnsignedLongs.remainder(value, val.value));
    146      }
    147
    148      /**
    149       * Returns the value of this {@code UnsignedLong} as an {@code int}.
    150       */
    151      @Override
    152      public int intValue() {
    153        return (int) value;
    154      }
    155
    156      /**
    157       * Returns the value of this {@code UnsignedLong} as a {@code long}. This is an inverse operation
    158       * to {@link #asUnsigned}.
    159       *
    160       * <p>Note that if this {@code UnsignedLong} holds a value {@code >= 2^63}, the returned value
    161       * will be equal to {@code this - 2^64}.
    162       */
    163      @Override
    164      public long longValue() {
    165        return value;
    166      }
    167
    168      /**
    169       * Returns the value of this {@code UnsignedLong} as a {@code float}, analogous to a widening
    170       * primitive conversion from {@code long} to {@code float}, and correctly rounded.
    171       */
    172      @Override
    173      public float floatValue() {
    174        @SuppressWarnings("cast")
    175        float fValue = (float) (value & UNSIGNED_MASK);
    176        if (value < 0) {
    177          fValue += 0x1.0p63f;
    178        }
    179        return fValue;
    180      }
    181
    182      /**
    183       * Returns the value of this {@code UnsignedLong} as a {@code double}, analogous to a widening
    184       * primitive conversion from {@code long} to {@code double}, and correctly rounded.
    185       */
    186      @Override
    187      public double doubleValue() {
    188        @SuppressWarnings("cast")
    189        double dValue = (double) (value & UNSIGNED_MASK);
    190        if (value < 0) {
    191          dValue += 0x1.0p63;
    192        }
    193        return dValue;
    194      }
    195
    196      /**
    197       * Returns the value of this {@code UnsignedLong} as a {@link BigInteger}.
    198       */
    199      public BigInteger bigIntegerValue() {
    200        BigInteger bigInt = BigInteger.valueOf(value & UNSIGNED_MASK);
    201        if (value < 0) {
    202          bigInt = bigInt.setBit(Long.SIZE - 1);
    203        }
    204        return bigInt;
    205      }
    206
    207      @Override
    208      public int compareTo(UnsignedLong o) {
    209        checkNotNull(o);
    210        return UnsignedLongs.compare(value, o.value);
    211      }
    212
    213      @Override
    214      public int hashCode() {
    215        return Longs.hashCode(value);
    216      }
    217
    218      @Override
    219      public boolean equals(@Nullable Object obj) {
    220        if (obj instanceof UnsignedLong) {
    221          UnsignedLong other = (UnsignedLong) obj;
    222          return value == other.value;
    223        }
    224        return false;
    225      }
    226
    227      /**
    228       * Returns a string representation of the {@code UnsignedLong} value, in base 10.
    229       */
    230      @Override
    231      public String toString() {
    232        return UnsignedLongs.toString(value);
    233      }
    234
    235      /**
    236       * Returns a string representation of the {@code UnsignedLong} value, in base {@code radix}. If
    237       * {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix
    238       * {@code 10} is used.
    239       */
    240      public String toString(int radix) {
    241        return UnsignedLongs.toString(value, radix);
    242      }
    243    }