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