| /* |
| * Copyright 2008 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package java.lang; |
| |
| /** |
| * Wraps a primitive <code>long</code> as an object. |
| */ |
| public final class Long extends Number implements Comparable<Long> { |
| |
| /** |
| * Use nested class to avoid clinit on outer. |
| */ |
| static class BoxedValues { |
| // Box values according to JLS - between -128 and 127 |
| static Long[] boxedValues = new Long[256]; |
| } |
| |
| static class HexLookup { |
| /** |
| * Super fast char->digit conversion. |
| */ |
| static int[] hexLookup = new int[0]; |
| |
| static { |
| for (char c = '0'; c <= '9'; ++c) { |
| hexLookup[c] = c - '0'; |
| } |
| for (char c = 'A'; c <= 'F'; ++c) { |
| hexLookup[c] = c - 'A' + 10; |
| } |
| for (char c = 'a'; c <= 'f'; ++c) { |
| hexLookup[c] = c - 'a' + 10; |
| } |
| } |
| } |
| |
| public static final long MAX_VALUE = 0x7fffffffffffffffL; |
| public static final long MIN_VALUE = 0x8000000000000000L; |
| public static final int SIZE = 64; |
| |
| public static int bitCount(long i) { |
| int high = (int) (i >> 32); |
| int low = (int) i; |
| return Integer.bitCount(high) + Integer.bitCount(low); |
| } |
| |
| public static Long decode(String s) throws NumberFormatException { |
| __Decode decode = __decodeNumberString(s); |
| return new Long(parseLong(decode.payload, decode.radix)); |
| } |
| |
| /** |
| * @skip Here for shared implementation with Arrays.hashCode |
| */ |
| public static int hashCode(long l) { |
| return (int) l; |
| } |
| |
| public static long highestOneBit(long i) { |
| int high = (int) (i >> 32); |
| if (high != 0) { |
| return ((long) Integer.highestOneBit(high)) << 32; |
| } else { |
| return Integer.highestOneBit((int) i); |
| } |
| } |
| |
| public static long lowestOneBit(long i) { |
| return i & -i; |
| } |
| |
| public static int numberOfLeadingZeros(long i) { |
| int high = (int) (i >> 32); |
| if (high != 0) { |
| return Integer.numberOfLeadingZeros(high); |
| } else { |
| return Integer.numberOfLeadingZeros((int) i) + 32; |
| } |
| } |
| |
| public static int numberOfTrailingZeros(long i) { |
| int low = (int) i; |
| if (low != 0) { |
| return Integer.numberOfTrailingZeros(low); |
| } else { |
| return Integer.numberOfTrailingZeros((int) (i >> 32)) + 32; |
| } |
| } |
| |
| public static long parseLong(String s) throws NumberFormatException { |
| return parseLong(s, 10); |
| } |
| |
| public static long parseLong(String s, int radix) throws NumberFormatException { |
| return __parseAndValidateLong(s, radix); |
| } |
| |
| public static long reverse(long i) { |
| int high = (int) (i >>> 32); |
| int low = (int) i; |
| return ((long) Integer.reverse(low) << 32) |
| | (Integer.reverse(high) & 0xffffffffL); |
| } |
| |
| public static long reverseBytes(long i) { |
| int high = (int) (i >>> 32); |
| int low = (int) i; |
| return ((long) Integer.reverseBytes(low) << 32) |
| | (Integer.reverseBytes(high) & 0xffffffffL); |
| } |
| |
| public static long rotateLeft(long i, int distance) { |
| while (distance-- > 0) { |
| i = i << 1 | ((i < 0) ? 1 : 0); |
| } |
| return i; |
| } |
| |
| public static long rotateRight(long i, int distance) { |
| long ui = i & MAX_VALUE; // avoid sign extension |
| long carry = (i < 0) ? 0x4000000000000000L : 0; // MIN_VALUE rightshifted 1 |
| while (distance-- > 0) { |
| long nextcarry = ui & 1; |
| ui = carry | (ui >> 1); |
| carry = (nextcarry == 0) ? 0 : 0x4000000000000000L; |
| } |
| if (carry != 0) { |
| ui = ui | MIN_VALUE; |
| } |
| return ui; |
| } |
| |
| public static int signum(long i) { |
| if (i == 0) { |
| return 0; |
| } else if (i < 0) { |
| return -1; |
| } else { |
| return 1; |
| } |
| } |
| |
| public static String toBinaryString(long value) { |
| return toPowerOfTwoString(value, 1); |
| } |
| |
| public static String toHexString(long value) { |
| return toPowerOfTwoString(value, 4); |
| } |
| |
| public static String toOctalString(long value) { |
| return toPowerOfTwoString(value, 3); |
| } |
| |
| public static String toString(long value) { |
| return String.valueOf(value); |
| } |
| |
| public static String toString(long value, int intRadix) { |
| if (intRadix == 10 || intRadix < Character.MIN_RADIX |
| || intRadix > Character.MAX_RADIX) { |
| return String.valueOf(value); |
| } |
| |
| final int bufSize = 65; |
| char[] buf = new char[bufSize]; |
| char[] digits = __Digits.digits; |
| int pos = bufSize - 1; |
| // Cache a converted version for performance (pure long ops are faster). |
| long radix = intRadix; |
| if (value >= 0) { |
| while (value >= radix) { |
| buf[pos--] = digits[(int) (value % radix)]; |
| value /= radix; |
| } |
| buf[pos] = digits[(int) value]; |
| } else { |
| while (value <= -radix) { |
| buf[pos--] = digits[(int) -(value % radix)]; |
| value /= radix; |
| } |
| buf[pos--] = digits[(int) -value]; |
| buf[pos] = '-'; |
| } |
| return String.__valueOf(buf, pos, bufSize); |
| } |
| |
| public static Long valueOf(long i) { |
| if (i > -129 && i < 128) { |
| int rebase = (int) i + 128; |
| Long result = BoxedValues.boxedValues[rebase]; |
| if (result == null) { |
| result = BoxedValues.boxedValues[rebase] = new Long(i); |
| } |
| return result; |
| } |
| return new Long(i); |
| } |
| |
| public static Long valueOf(String s) throws NumberFormatException { |
| return new Long(Long.parseLong(s)); |
| } |
| |
| public static Long valueOf(String s, int radix) throws NumberFormatException { |
| return new Long(Long.parseLong(s, radix)); |
| } |
| |
| private static native int hexDigit(char c, String s) /*-{ |
| var val = @java.lang.Long.HexLookup::hexLookup[c]; |
| if (val == null) { |
| throw @java.lang.NumberFormatException::forInputString(Ljava/lang/String;)(s); |
| } |
| return val; |
| }-*/; |
| |
| private static long parseHex(String s) { |
| // TODO: make faster using int math! |
| int len = s.length(); |
| if (len > 16) { |
| throw NumberFormatException.forInputString(s); |
| } |
| long result = 0; |
| for (int i = 0; i < len; ++i) { |
| result <<= 4; |
| result += hexDigit(s.charAt(i), s); |
| } |
| return result; |
| } |
| |
| private static String toPowerOfTwoString(long value, int shift) { |
| // TODO: make faster using int math! |
| final int bufSize = 64 / shift; |
| long bitMask = (1 << shift) - 1; |
| char[] buf = new char[bufSize]; |
| char[] digits = __Digits.digits; |
| int pos = bufSize - 1; |
| if (value >= 0) { |
| while (value > bitMask) { |
| buf[pos--] = digits[(int) (value & bitMask)]; |
| value >>= shift; |
| } |
| } else { |
| while (pos > 0) { |
| buf[pos--] = digits[(int) (value & bitMask)]; |
| value >>= shift; |
| } |
| } |
| buf[pos] = digits[(int) (value & bitMask)]; |
| return String.__valueOf(buf, pos, bufSize); |
| } |
| |
| private final transient long value; |
| |
| public Long(long value) { |
| this.value = value; |
| } |
| |
| public Long(String s) { |
| value = parseLong(s); |
| } |
| |
| @Override |
| public byte byteValue() { |
| return (byte) value; |
| } |
| |
| public int compareTo(Long b) { |
| if (value < b.value) { |
| return -1; |
| } else if (value > b.value) { |
| return 1; |
| } else { |
| return 0; |
| } |
| } |
| |
| @Override |
| public double doubleValue() { |
| return value; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| return (o instanceof Long) && (((Long) o).value == value); |
| } |
| |
| @Override |
| public float floatValue() { |
| return value; |
| } |
| |
| @Override |
| public int hashCode() { |
| return hashCode(value); |
| } |
| |
| @Override |
| public int intValue() { |
| return (int) value; |
| } |
| |
| @Override |
| public long longValue() { |
| return value; |
| } |
| |
| @Override |
| public short shortValue() { |
| return (short) value; |
| } |
| |
| @Override |
| public String toString() { |
| return toString(value); |
| } |
| } |