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 long
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 Class TYPE = VMClassLoader.getPrimitiveClass ('J');
/**
* 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);
}
/**
* 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)
{
// Use the Integer toString for efficiency if possible.
if ((int) num == num)
return Integer.toString((int) num, radix);
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
// For negative numbers, print out the absolute value w/ a leading '-'.
// Use an array large enough for a binary number.
char[] buffer = new char[65];
int i = 65;
boolean isNeg = false;
if (num < 0)
{
isNeg = true;
num = -num;
// When the value is MIN_VALUE, it overflows when made positive
if (num < 0)
{
buffer[--i] = digits[(int) (-(num + radix) % radix)];
num = -(num / radix);
}
}
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, 65 - 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 s 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 new Long(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 new Long(parseLong(s, 10, false));
}
/**
* 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 s 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 new Long(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 ? new Long(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 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 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;
}
/**
* Behaves like compareTo(Long)
unless the Object
* is not a Long
.
*
* @param o the object to compare
* @return the comparison
* @throws ClassCastException if the argument is not a Long
* @see #compareTo(Long)
* @see Comparable
* @since 1.2
*/
public int compareTo(Object o)
{
return compareTo((Long) o);
}
/**
* 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)
{
// Use the Integer toUnsignedString for efficiency if possible.
// If NUM<0 then this particular optimization doesn't work
// properly.
if (num >= 0 && (int) num == num)
return Integer.toUnsignedString((int) num, exp);
// Use an array large enough for a binary number.
int mask = (1 << exp) - 1;
char[] buffer = new char[64];
int i = 64;
do
{
buffer[--i] = digits[(int) num & mask];
num >>>= exp;
}
while (num != 0);
// Package constructor avoids an array copy.
return new String(buffer, i, 64 - 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;
}
}