Long
represent primitive
* long
values.
*
* Additionally, this class provides various helper functions and variables
* related to longs.
*
* @author Paul Fisher
* @author John Keiser
* @author Warren Levy
* @author Eric Blake (ebb9@email.byu.edu)
* @author Tom Tromey (tromey@redhat.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @author Ian Rogers
* @since 1.0
* @status updated to 1.5
*/
public final class Long extends Number implements Comparablelong
can represent is
* -9223372036854775808L (or -263).
*/
public static final long MIN_VALUE = 0x8000000000000000L;
/**
* The maximum value a long
can represent is
* 9223372036854775807 (or 263 - 1).
*/
public static final long MAX_VALUE = 0x7fffffffffffffffL;
/**
* The primitive type long
is represented by this
* Class
object.
* @since 1.1
*/
public static final Classlong
.
* @since 1.5
*/
public static final int SIZE = 64;
// This caches some Long values, and is used by boxing
// conversions via valueOf(). We cache at least -128..127;
// these constants control how much we actually cache.
private static final int MIN_CACHE = -128;
private static final int MAX_CACHE = 127;
private static final Long[] longCache = new Long[MAX_CACHE - MIN_CACHE + 1];
static
{
for (int i=MIN_CACHE; i <= MAX_CACHE; i++)
longCache[i - MIN_CACHE] = new Long(i);
}
/**
* The immutable value of this Long.
*
* @serial the wrapped long
*/
private final long value;
/**
* Create a Long
object representing the value of the
* long
argument.
*
* @param value the value to use
*/
public Long(long value)
{
this.value = value;
}
/**
* Create a Long
object representing the value of the
* argument after conversion to a long
.
*
* @param s the string to convert
* @throws NumberFormatException if the String does not contain a long
* @see #valueOf(String)
*/
public Long(String s)
{
value = parseLong(s, 10, false);
}
/**
* Return the size of a string large enough to hold the given number
*
* @param num the number we want the string length for (must be positive)
* @param radix the radix (base) that will be used for the string
* @return a size sufficient for a string of num
*/
private static int stringSize(long num, int radix) {
int exp;
if (radix < 4)
{
exp = 1;
}
else if (radix < 8)
{
exp = 2;
}
else if (radix < 16)
{
exp = 3;
}
else if (radix < 32)
{
exp = 4;
}
else
{
exp = 5;
}
int size=0;
do
{
num >>>= exp;
size++;
}
while(num != 0);
return size;
}
/**
* Converts the long
to a String
using
* the specified radix (base). If the radix exceeds
* Character.MIN_RADIX
or Character.MAX_RADIX
, 10
* is used instead. If the result is negative, the leading character is
* '-' ('\\u002D'). The remaining characters come from
* Character.forDigit(digit, radix)
('0'-'9','a'-'z').
*
* @param num the long
to convert to String
* @param radix the radix (base) to use in the conversion
* @return the String
representation of the argument
*/
public static String toString(long num, int radix)
{
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
// Is the value negative?
boolean isNeg = num < 0;
// Is the string a single character?
if (!isNeg && num < radix)
return new String(digits, (int)num, 1, true);
// Compute string size and allocate buffer
// account for a leading '-' if the value is negative
int size;
int i;
char[] buffer;
if (isNeg)
{
num = -num;
// When the value is MIN_VALUE, it overflows when made positive
if (num < 0)
{
i = size = stringSize(MAX_VALUE, radix) + 2;
buffer = new char[size];
buffer[--i] = digits[(int) (-(num + radix) % radix)];
num = -(num / radix);
}
else
{
i = size = stringSize(num, radix) + 1;
buffer = new char[size];
}
}
else
{
i = size = stringSize(num, radix);
buffer = new char[size];
}
do
{
buffer[--i] = digits[(int) (num % radix)];
num /= radix;
}
while (num > 0);
if (isNeg)
buffer[--i] = '-';
// Package constructor avoids an array copy.
return new String(buffer, i, size - i, true);
}
/**
* Converts the long
to a String
assuming it is
* unsigned in base 16.
*
* @param l the long
to convert to String
* @return the String
representation of the argument
*/
public static String toHexString(long l)
{
return toUnsignedString(l, 4);
}
/**
* Converts the long
to a String
assuming it is
* unsigned in base 8.
*
* @param l the long
to convert to String
* @return the String
representation of the argument
*/
public static String toOctalString(long l)
{
return toUnsignedString(l, 3);
}
/**
* Converts the long
to a String
assuming it is
* unsigned in base 2.
*
* @param l the long
to convert to String
* @return the String
representation of the argument
*/
public static String toBinaryString(long l)
{
return toUnsignedString(l, 1);
}
/**
* Converts the long
to a String
and assumes
* a radix of 10.
*
* @param num the long
to convert to String
* @return the String
representation of the argument
* @see #toString(long, int)
*/
public static String toString(long num)
{
return toString(num, 10);
}
/**
* Converts the specified String
into an int
* using the specified radix (base). The string must not be null
* or empty. It may begin with an optional '-', which will negate the answer,
* provided that there are also valid digits. Each digit is parsed as if by
* Character.digit(d, radix)
, and must be in the range
* 0
to radix - 1
. Finally, the result must be
* within MIN_VALUE
to MAX_VALUE
, inclusive.
* Unlike Double.parseDouble, you may not have a leading '+'; and 'l' or
* 'L' as the last character is only valid in radices 22 or greater, where
* it is a digit and not a type indicator.
*
* @param str the String
to convert
* @param radix the radix (base) to use in the conversion
* @return the String
argument converted to long
* @throws NumberFormatException if s
cannot be parsed as a
* long
*/
public static long parseLong(String str, int radix)
{
return parseLong(str, radix, false);
}
/**
* Converts the specified String
into a long
.
* This function assumes a radix of 10.
*
* @param s the String
to convert
* @return the int
value of s
* @throws NumberFormatException if s
cannot be parsed as a
* long
* @see #parseLong(String, int)
*/
public static long parseLong(String s)
{
return parseLong(s, 10, false);
}
/**
* Creates a new Long
object using the String
* and specified radix (base).
*
* @param s the String
to convert
* @param radix the radix (base) to convert with
* @return the new Long
* @throws NumberFormatException if s
cannot be parsed as a
* long
* @see #parseLong(String, int)
*/
public static Long valueOf(String s, int radix)
{
return valueOf(parseLong(s, radix, false));
}
/**
* Creates a new Long
object using the String
,
* assuming a radix of 10.
*
* @param s the String
to convert
* @return the new Long
* @throws NumberFormatException if s
cannot be parsed as a
* long
* @see #Long(String)
* @see #parseLong(String)
*/
public static Long valueOf(String s)
{
return valueOf(parseLong(s, 10, false));
}
/**
* Returns a Long
object wrapping the value.
*
* @param val the value to wrap
* @return the Long
* @since 1.5
*/
public static Long valueOf(long val)
{
if (val < MIN_CACHE || val > MAX_CACHE)
return new Long(val);
else
return longCache[((int)val) - MIN_CACHE];
}
/**
* Convert the specified String
into a Long
.
* The String
may represent decimal, hexadecimal, or
* octal numbers.
*
* The extended BNF grammar is as follows:
*
* DecodableString: * ( [* Finally, the value must be in the range-
] DecimalNumber ) * | ( [-
] (0x
|0X
* |#
) HexDigit { HexDigit } ) * | ( [-
]0
{ OctalDigit } ) * DecimalNumber: * DecimalDigit except '0' { DecimalDigit } * DecimalDigit: * Character.digit(d, 10) has value 0 to 9 * OctalDigit: * Character.digit(d, 8) has value 0 to 7 * DecimalDigit: * Character.digit(d, 16) has value 0 to 15 *
MIN_VALUE
to
* MAX_VALUE
, or an exception is thrown. Note that you cannot
* use a trailing 'l' or 'L', unlike in Java source code.
*
* @param str the String
to interpret
* @return the value of the String as a Long
* @throws NumberFormatException if s
cannot be parsed as a
* long
* @throws NullPointerException if s
is null
* @since 1.2
*/
public static Long decode(String str)
{
return valueOf(parseLong(str, 10, true));
}
/**
* Return the value of this Long
as a byte
.
*
* @return the byte value
*/
public byte byteValue()
{
return (byte) value;
}
/**
* Return the value of this Long
as a short
.
*
* @return the short value
*/
public short shortValue()
{
return (short) value;
}
/**
* Return the value of this Long
as an int
.
*
* @return the int value
*/
public int intValue()
{
return (int) value;
}
/**
* Return the value of this Long
.
*
* @return the long value
*/
public long longValue()
{
return value;
}
/**
* Return the value of this Long
as a float
.
*
* @return the float value
*/
public float floatValue()
{
return value;
}
/**
* Return the value of this Long
as a double
.
*
* @return the double value
*/
public double doubleValue()
{
return value;
}
/**
* Converts the Long
value to a String
and
* assumes a radix of 10.
*
* @return the String
representation
*/
public String toString()
{
return toString(value, 10);
}
/**
* Return a hashcode representing this Object. Long
's hash
* code is calculated by (int) (value ^ (value >> 32))
.
*
* @return this Object's hash code
*/
public int hashCode()
{
return (int) (value ^ (value >>> 32));
}
/**
* Returns true
if obj
is an instance of
* Long
and represents the same long value.
*
* @param obj the object to compare
* @return whether these Objects are semantically equal
*/
public boolean equals(Object obj)
{
return obj instanceof Long && value == ((Long) obj).value;
}
/**
* Get the specified system property as a Long
. The
* decode()
method will be used to interpret the value of
* the property.
*
* @param nm the name of the system property
* @return the system property as a Long
, or null if the
* property is not found or cannot be decoded
* @throws SecurityException if accessing the system property is forbidden
* @see System#getProperty(String)
* @see #decode(String)
*/
public static Long getLong(String nm)
{
return getLong(nm, null);
}
/**
* Get the specified system property as a Long
, or use a
* default long
value if the property is not found or is not
* decodable. The decode()
method will be used to interpret
* the value of the property.
*
* @param nm the name of the system property
* @param val the default value
* @return the value of the system property, or the default
* @throws SecurityException if accessing the system property is forbidden
* @see System#getProperty(String)
* @see #decode(String)
*/
public static Long getLong(String nm, long val)
{
Long result = getLong(nm, null);
return result == null ? valueOf(val) : result;
}
/**
* Get the specified system property as a Long
, or use a
* default Long
value if the property is not found or is
* not decodable. The decode()
method will be used to
* interpret the value of the property.
*
* @param nm the name of the system property
* @param def the default value
* @return the value of the system property, or the default
* @throws SecurityException if accessing the system property is forbidden
* @see System#getProperty(String)
* @see #decode(String)
*/
public static Long getLong(String nm, Long def)
{
if (nm == null || "".equals(nm))
return def;
nm = System.getProperty(nm);
if (nm == null)
return def;
try
{
return decode(nm);
}
catch (NumberFormatException e)
{
return def;
}
}
/**
* Compare two Longs numerically by comparing their long
* values. The result is positive if the first is greater, negative if the
* second is greater, and 0 if the two are equal.
*
* @param l the Long to compare
* @return the comparison
* @since 1.2
*/
public int compareTo(Long l)
{
if (value == l.value)
return 0;
// Returns just -1 or 1 on inequality; doing math might overflow the long.
return value > l.value ? 1 : -1;
}
/**
* Return the number of bits set in x.
* @param x value to examine
* @since 1.5
*/
public static int bitCount(long x)
{
// Successively collapse alternating bit groups into a sum.
x = ((x >> 1) & 0x5555555555555555L) + (x & 0x5555555555555555L);
x = ((x >> 2) & 0x3333333333333333L) + (x & 0x3333333333333333L);
int v = (int) ((x >>> 32) + x);
v = ((v >> 4) & 0x0f0f0f0f) + (v & 0x0f0f0f0f);
v = ((v >> 8) & 0x00ff00ff) + (v & 0x00ff00ff);
return ((v >> 16) & 0x0000ffff) + (v & 0x0000ffff);
}
/**
* Rotate x to the left by distance bits.
* @param x the value to rotate
* @param distance the number of bits by which to rotate
* @since 1.5
*/
public static long rotateLeft(long x, int distance)
{
// This trick works because the shift operators implicitly mask
// the shift count.
return (x << distance) | (x >>> - distance);
}
/**
* Rotate x to the right by distance bits.
* @param x the value to rotate
* @param distance the number of bits by which to rotate
* @since 1.5
*/
public static long rotateRight(long x, int distance)
{
// This trick works because the shift operators implicitly mask
// the shift count.
return (x << - distance) | (x >>> distance);
}
/**
* Find the highest set bit in value, and return a new value
* with only that bit set.
* @param value the value to examine
* @since 1.5
*/
public static long highestOneBit(long value)
{
value |= value >>> 1;
value |= value >>> 2;
value |= value >>> 4;
value |= value >>> 8;
value |= value >>> 16;
value |= value >>> 32;
return value ^ (value >>> 1);
}
/**
* Return the number of leading zeros in value.
* @param value the value to examine
* @since 1.5
*/
public static int numberOfLeadingZeros(long value)
{
value |= value >>> 1;
value |= value >>> 2;
value |= value >>> 4;
value |= value >>> 8;
value |= value >>> 16;
value |= value >>> 32;
return bitCount(~value);
}
/**
* Find the lowest set bit in value, and return a new value
* with only that bit set.
* @param value the value to examine
* @since 1.5
*/
public static long lowestOneBit(long value)
{
// Classic assembly trick.
return value & - value;
}
/**
* Find the number of trailing zeros in value.
* @param value the value to examine
* @since 1.5
*/
public static int numberOfTrailingZeros(long value)
{
return bitCount((value & -value) - 1);
}
/**
* Return 1 if x is positive, -1 if it is negative, and 0 if it is
* zero.
* @param x the value to examine
* @since 1.5
*/
public static int signum(long x)
{
return (int) ((x >> 63) | (-x >>> 63));
// The LHS propagates the sign bit through every bit in the word;
// if X < 0, every bit is set to 1, else 0. if X > 0, the RHS
// negates x and shifts the resulting 1 in the sign bit to the
// LSB, leaving every other bit 0.
// Hacker's Delight, Section 2-7
}
/**
* Reverse the bytes in val.
* @since 1.5
*/
public static long reverseBytes(long val)
{
int hi = Integer.reverseBytes((int) val);
int lo = Integer.reverseBytes((int) (val >>> 32));
return (((long) hi) << 32) | lo;
}
/**
* Reverse the bits in val.
* @since 1.5
*/
public static long reverse(long val)
{
long hi = Integer.reverse((int) val) & 0xffffffffL;
long lo = Integer.reverse((int) (val >>> 32)) & 0xffffffffL;
return (hi << 32) | lo;
}
/**
* Helper for converting unsigned numbers to String.
*
* @param num the number
* @param exp log2(digit) (ie. 1, 3, or 4 for binary, oct, hex)
*/
private static String toUnsignedString(long num, int exp)
{
// Compute string length
int size = 1;
long copy = num >>> exp;
while (copy != 0)
{
size++;
copy >>>= exp;
}
// Quick path for single character strings
if (size == 1)
return new String(digits, (int)num, 1, true);
// Encode into buffer
int mask = (1 << exp) - 1;
char[] buffer = new char[size];
int i = size;
do
{
buffer[--i] = digits[(int) num & mask];
num >>>= exp;
}
while (num != 0);
// Package constructor avoids an array copy.
return new String(buffer, i, size - i, true);
}
/**
* Helper for parsing longs.
*
* @param str the string to parse
* @param radix the radix to use, must be 10 if decode is true
* @param decode if called from decode
* @return the parsed long value
* @throws NumberFormatException if there is an error
* @throws NullPointerException if decode is true and str is null
* @see #parseLong(String, int)
* @see #decode(String)
*/
private static long parseLong(String str, int radix, boolean decode)
{
if (! decode && str == null)
throw new NumberFormatException();
int index = 0;
int len = str.length();
boolean isNeg = false;
if (len == 0)
throw new NumberFormatException();
int ch = str.charAt(index);
if (ch == '-')
{
if (len == 1)
throw new NumberFormatException();
isNeg = true;
ch = str.charAt(++index);
}
if (decode)
{
if (ch == '0')
{
if (++index == len)
return 0;
if ((str.charAt(index) & ~('x' ^ 'X')) == 'X')
{
radix = 16;
index++;
}
else
radix = 8;
}
else if (ch == '#')
{
radix = 16;
index++;
}
}
if (index == len)
throw new NumberFormatException();
long max = MAX_VALUE / radix;
// We can't directly write `max = (MAX_VALUE + 1) / radix'.
// So instead we fake it.
if (isNeg && MAX_VALUE % radix == radix - 1)
++max;
long val = 0;
while (index < len)
{
if (val < 0 || val > max)
throw new NumberFormatException();
ch = Character.digit(str.charAt(index++), radix);
val = val * radix + ch;
if (ch < 0 || (val < 0 && (! isNeg || val != MIN_VALUE)))
throw new NumberFormatException();
}
return isNeg ? -val : val;
}
}