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      
152      @Override
153      public int intValue() {
154        return (int) value;
155      }
156    
157      /**
158       * Returns the value of this {@code UnsignedLong} as a {@code long}. This is an inverse operation
159       * to {@link #asUnsigned}.
160       * 
161       * <p>Note that if this {@code UnsignedLong} holds a value {@code >= 2^63}, the returned value
162       * will be equal to {@code this - 2^64}.
163       */
164      
165      @Override
166      public long longValue() {
167        return value;
168      }
169    
170      /**
171       * Returns the value of this {@code UnsignedLong} as a {@code float}, analogous to a widening
172       * primitive conversion from {@code long} to {@code float}, and correctly rounded.
173       */
174      
175      @Override
176      public float floatValue() {
177        @SuppressWarnings("cast")
178        float fValue = (float) (value & UNSIGNED_MASK);
179        if (value < 0) {
180          fValue += 0x1.0p63f;
181        }
182        return fValue;
183      }
184    
185      /**
186       * Returns the value of this {@code UnsignedLong} as a {@code double}, analogous to a widening
187       * primitive conversion from {@code long} to {@code double}, and correctly rounded.
188       */
189      
190      @Override
191      public double doubleValue() {
192        @SuppressWarnings("cast")
193        double dValue = (double) (value & UNSIGNED_MASK);
194        if (value < 0) {
195          dValue += 0x1.0p63;
196        }
197        return dValue;
198      }
199    
200      /**
201       * Returns the value of this {@code UnsignedLong} as a {@link BigInteger}.
202       */
203      public BigInteger bigIntegerValue() {
204        BigInteger bigInt = BigInteger.valueOf(value & UNSIGNED_MASK);
205        if (value < 0) {
206          bigInt = bigInt.setBit(Long.SIZE - 1);
207        }
208        return bigInt;
209      }
210    
211      public int compareTo(UnsignedLong o) {
212        checkNotNull(o);
213        return UnsignedLongs.compare(value, o.value);
214      }
215    
216      
217      @Override
218      public int hashCode() {
219        return Longs.hashCode(value);
220      }
221    
222      
223      @Override
224      public boolean equals(@Nullable Object obj) {
225        if (obj instanceof UnsignedLong) {
226          UnsignedLong other = (UnsignedLong) obj;
227          return value == other.value;
228        }
229        return false;
230      }
231    
232      /**
233       * Returns a string representation of the {@code UnsignedLong} value, in base 10.
234       */
235      
236      @Override
237      public String toString() {
238        return UnsignedLongs.toString(value);
239      }
240    
241      /**
242       * Returns a string representation of the {@code UnsignedLong} value, in base {@code radix}. If
243       * {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix
244       * {@code 10} is used.
245       */
246      public String toString(int radix) {
247        return UnsignedLongs.toString(value, radix);
248      }
249    }