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    }