106 |
*/ |
*/ |
107 |
public Long(String s) |
public Long(String s) |
108 |
{ |
{ |
109 |
value = parseLong(s, 10); |
value = parseLong(s, 10, false); |
110 |
} |
} |
111 |
|
|
112 |
/** |
/** |
123 |
*/ |
*/ |
124 |
public static String toString(long num, int radix) |
public static String toString(long num, int radix) |
125 |
{ |
{ |
|
// Use optimized method for the typical case. |
|
|
if (radix == 10 || |
|
|
radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) |
|
|
return toString(num); |
|
|
|
|
126 |
// Use the Integer toString for efficiency if possible. |
// Use the Integer toString for efficiency if possible. |
127 |
if ((int) num == num) |
if ((int) num == num) |
128 |
return Integer.toString((int) num, radix); |
return Integer.toString((int) num, radix); |
129 |
|
|
130 |
|
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) |
131 |
|
radix = 10; |
132 |
|
|
133 |
// For negative numbers, print out the absolute value w/ a leading '-'. |
// For negative numbers, print out the absolute value w/ a leading '-'. |
134 |
// Use an array large enough for a binary number. |
// Use an array large enough for a binary number. |
135 |
char[] buffer = new char[65]; |
char[] buffer = new char[65]; |
136 |
int i = 65; |
int i = 65; |
137 |
boolean isNeg; |
boolean isNeg = false; |
138 |
if (num < 0) |
if (num < 0) |
139 |
{ |
{ |
140 |
isNeg = true; |
isNeg = true; |
142 |
|
|
143 |
// When the value is MIN_VALUE, it overflows when made positive |
// When the value is MIN_VALUE, it overflows when made positive |
144 |
if (num < 0) |
if (num < 0) |
145 |
{ |
return "" + MIN_VALUE; |
|
buffer[--i] = Character.forDigit((int) (-(num + radix) % radix), |
|
|
radix); |
|
|
num = -(num / radix); |
|
|
} |
|
146 |
} |
} |
|
else |
|
|
isNeg = false; |
|
147 |
|
|
148 |
do |
do |
149 |
{ |
{ |
150 |
buffer[--i] = Character.forDigit((int) (num % radix), radix); |
buffer[--i] = digits[(int) (num % radix)]; |
151 |
num /= radix; |
num /= radix; |
152 |
} |
} |
153 |
while (num > 0); |
while (num > 0); |
204 |
*/ |
*/ |
205 |
public static String toString(long num) |
public static String toString(long num) |
206 |
{ |
{ |
207 |
// Use the Integer toString for efficiency if possible. |
return toString(num, 10); |
|
if ((int) num == num) |
|
|
return String.valueOf((int) num); |
|
|
|
|
|
// Use an array large enough for "-9223372036854775808"; i.e. 20 chars. |
|
|
char[] buffer = new char[20]; |
|
|
int i = 20; |
|
|
boolean isNeg; |
|
|
if (num < 0) |
|
|
{ |
|
|
isNeg = true; |
|
|
num = -(num); |
|
|
if (num < 0) |
|
|
{ |
|
|
// Must be MIN_VALUE, so handle this special case. |
|
|
buffer[--i] = '8'; |
|
|
num = 922337203685477580L; |
|
|
} |
|
|
} |
|
|
else |
|
|
isNeg = false; |
|
|
|
|
|
do |
|
|
{ |
|
|
buffer[--i] = (char) ((int) '0' + (num % 10)); |
|
|
num /= 10; |
|
|
} |
|
|
while (num > 0); |
|
|
|
|
|
if (isNeg) |
|
|
buffer[--i] = '-'; |
|
|
|
|
|
return String.valueOf(buffer, i, 20 - i); |
|
208 |
} |
} |
209 |
|
|
210 |
/** |
/** |
227 |
*/ |
*/ |
228 |
public static long parseLong(String str, int radix) |
public static long parseLong(String str, int radix) |
229 |
{ |
{ |
230 |
final int len; |
return parseLong(str, radix, false); |
|
|
|
|
if ((len = str.length()) == 0 || radix < Character.MIN_RADIX |
|
|
|| radix > Character.MAX_RADIX) |
|
|
throw new NumberFormatException(); |
|
|
|
|
|
boolean isNeg = false; |
|
|
int index = 0; |
|
|
if (str.charAt(index) == '-') |
|
|
if (len > 1) |
|
|
{ |
|
|
isNeg = true; |
|
|
index++; |
|
|
} |
|
|
else |
|
|
throw new NumberFormatException(); |
|
|
|
|
|
return parseLong(str, index, len, isNeg, radix); |
|
231 |
} |
} |
232 |
|
|
233 |
/** |
/** |
242 |
*/ |
*/ |
243 |
public static long parseLong(String s) |
public static long parseLong(String s) |
244 |
{ |
{ |
245 |
return parseLong(s, 10); |
return parseLong(s, 10, false); |
246 |
} |
} |
247 |
|
|
248 |
/** |
/** |
258 |
*/ |
*/ |
259 |
public static Long valueOf(String s, int radix) |
public static Long valueOf(String s, int radix) |
260 |
{ |
{ |
261 |
return new Long(parseLong(s, radix)); |
return new Long(parseLong(s, radix, false)); |
262 |
} |
} |
263 |
|
|
264 |
/** |
/** |
274 |
*/ |
*/ |
275 |
public static Long valueOf(String s) |
public static Long valueOf(String s) |
276 |
{ |
{ |
277 |
return new Long(parseLong(s, 10)); |
return new Long(parseLong(s, 10, false)); |
278 |
} |
} |
279 |
|
|
280 |
/** |
/** |
298 |
* <em>DecimalDigit</em>: |
* <em>DecimalDigit</em>: |
299 |
* <em>Character.digit(d, 16) has value 0 to 15</em> |
* <em>Character.digit(d, 16) has value 0 to 15</em> |
300 |
* </pre> |
* </pre> |
301 |
* Note that you cannot decode MIN_VALUE, as the specification requires |
* Finally, the value must be in the range <code>MIN_VALUE</code> to |
302 |
* that the digits be parsed before negating the result, but |
* <code>MAX_VALUE</code>, or an exception is thrown. Note that you cannot |
303 |
* 9223372036854775808 will not fit in a long. Also, you may not use a |
* use a trailing 'l' or 'L', unlike in Java source code. |
|
* trailing 'l' or 'L', unlike in Java source code. |
|
304 |
* |
* |
305 |
* @param s the <code>String</code> to interpret |
* @param s the <code>String</code> to interpret |
306 |
* @return the value of the String as a <code>Long</code> |
* @return the value of the String as a <code>Long</code> |
307 |
* @throws NumberFormatException if <code>s</code> cannot be parsed as a |
* @throws NumberFormatException if <code>s</code> cannot be parsed as a |
308 |
* <code>long</code> |
* <code>long</code> |
309 |
* @throws NullPointerException if s is null |
* @throws NullPointerException if <code>s</code> is null |
310 |
* @since 1.2 |
* @since 1.2 |
311 |
*/ |
*/ |
312 |
public static Long decode(String str) |
public static Long decode(String str) |
313 |
{ |
{ |
314 |
boolean isNeg = false; |
return new Long(parseLong(str, 10, true)); |
|
int index = 0; |
|
|
int radix = 10; |
|
|
final int len; |
|
|
|
|
|
if ((len = str.length()) == 0) |
|
|
throw new NumberFormatException(); |
|
|
|
|
|
// Negative numbers are always radix 10. |
|
|
if (str.charAt(0) == '-') |
|
|
{ |
|
|
radix = 10; |
|
|
index++; |
|
|
isNeg = true; |
|
|
} |
|
|
else if (str.charAt(index) == '#') |
|
|
{ |
|
|
radix = 16; |
|
|
index++; |
|
|
} |
|
|
else if (str.charAt(index) == '0') |
|
|
{ |
|
|
// Check if str is just "0" |
|
|
if (len == 1) |
|
|
return new Long(0L); |
|
|
|
|
|
index++; |
|
|
if (str.charAt(index) == 'x') |
|
|
{ |
|
|
radix = 16; |
|
|
index++; |
|
|
} |
|
|
else |
|
|
radix = 8; |
|
|
} |
|
|
|
|
|
if (index >= len) |
|
|
throw new NumberFormatException(); |
|
|
|
|
|
return new Long(parseLong(str, index, len, isNeg, radix)); |
|
315 |
} |
} |
316 |
|
|
317 |
/** |
/** |
459 |
*/ |
*/ |
460 |
public static Long getLong(String nm, Long def) |
public static Long getLong(String nm, Long def) |
461 |
{ |
{ |
462 |
String val = System.getProperty(nm); |
if (nm == null || "".equals(nm)) |
463 |
if (val == null) |
return def; |
464 |
|
nm = System.getProperty(nm); |
465 |
|
if (nm == null) |
466 |
return def; |
return def; |
467 |
try |
try |
468 |
{ |
{ |
488 |
if (value == l.value) |
if (value == l.value) |
489 |
return 0; |
return 0; |
490 |
// Returns just -1 or 1 on inequality; doing math might overflow the long. |
// Returns just -1 or 1 on inequality; doing math might overflow the long. |
491 |
return value > i.value ? 1 : -1; |
return value > l.value ? 1 : -1; |
492 |
} |
} |
493 |
|
|
494 |
/** |
/** |
516 |
private static String toUnsignedString(long num, int exp) |
private static String toUnsignedString(long num, int exp) |
517 |
{ |
{ |
518 |
// Use an array large enough for a binary number. |
// Use an array large enough for a binary number. |
519 |
int radix = 1 << exp; |
int mask = (1 << exp) - 1; |
|
int mask = radix - 1; |
|
520 |
char[] buffer = new char[64]; |
char[] buffer = new char[64]; |
521 |
int i = 64; |
int i = 64; |
522 |
do |
do |
523 |
{ |
{ |
524 |
buffer[--i] = Character.forDigit((int) num & mask, radix); |
buffer[--i] = digits[(int) num & mask]; |
525 |
num = num >>> exp; |
num >>>= exp; |
526 |
} |
} |
527 |
while (num != 0); |
while (num != 0); |
528 |
|
|
533 |
* Helper for parsing longs. |
* Helper for parsing longs. |
534 |
* |
* |
535 |
* @param str the string to parse |
* @param str the string to parse |
536 |
* @param index the index to start at |
* @param radix the radix to use, must be 10 if decode is true |
537 |
* @param len the string length |
* @param decode if called from decode |
|
* @param isNeg if the result should be negated |
|
|
* @param radix the radix to use |
|
538 |
* @return the parsed long value |
* @return the parsed long value |
539 |
* @throws NumberFormatException if there is an error |
* @throws NumberFormatException if there is an error |
540 |
|
* @throws NullPointerException if decode is true and str is null |
541 |
|
* @see #parseLong(String, int) |
542 |
|
* @see #decode(String) |
543 |
*/ |
*/ |
544 |
private static long parseLong(String str, int index, int len, boolean isNeg, |
private static long parseLong(String str, int radix, boolean decode) |
|
int radix) |
|
545 |
{ |
{ |
546 |
long val = 0; |
if (! decode && str == null) |
547 |
int digval; |
throw new NumberFormatException(); |
548 |
|
int index = 0; |
549 |
long max = MAX_VALUE / radix; |
int len = str.length(); |
550 |
// We can't directly write `max = (MAX_VALUE + 1) / radix'. |
boolean isNeg = false; |
551 |
// So instead we fake it. |
if (len == 0) |
552 |
if (isNeg && MAX_VALUE % radix == radix - 1) |
throw new NumberFormatException(); |
553 |
++max; |
int ch = str.charAt(index); |
554 |
|
if (ch == '-') |
|
for ( ; index < len; index++) |
|
555 |
{ |
{ |
556 |
if (val < 0 || val > max) |
if (len == 1) |
|
throw new NumberFormatException(); |
|
|
|
|
|
if ((digval = Character.digit(str.charAt(index), radix)) < 0) |
|
557 |
throw new NumberFormatException(); |
throw new NumberFormatException(); |
558 |
|
isNeg = true; |
559 |
// Throw an exception for overflow if result is negative. |
ch = str.charAt(++index); |
560 |
// However, we special-case the most negative value. |
} |
561 |
val = val * radix + digval; |
if (decode) |
562 |
if (val < 0 && (! isNeg || val != MIN_VALUE)) |
{ |
563 |
|
if (ch == '0') |
564 |
|
{ |
565 |
|
if (++index == len) |
566 |
|
return 0; |
567 |
|
if ((str.charAt(index) & ~('x' ^ 'X')) == 'X') |
568 |
|
{ |
569 |
|
radix = 16; |
570 |
|
index++; |
571 |
|
} |
572 |
|
else |
573 |
|
radix = 8; |
574 |
|
} |
575 |
|
else if (ch == '#') |
576 |
|
{ |
577 |
|
radix = 16; |
578 |
|
index++; |
579 |
|
} |
580 |
|
} |
581 |
|
if (index == len) |
582 |
|
throw new NumberFormatException(); |
583 |
|
long val = 0; |
584 |
|
while (index < len) |
585 |
|
{ |
586 |
|
ch = Character.digit(str.charAt(index++), radix); |
587 |
|
val = val * radix + ch; |
588 |
|
if (ch < 0 || (val < 0 && (index < len || ! isNeg |
589 |
|
|| val != MIN_VALUE))) |
590 |
throw new NumberFormatException(); |
throw new NumberFormatException(); |
591 |
} |
} |
|
|
|
592 |
return isNeg ? -val : val; |
return isNeg ? -val : val; |
593 |
} |
} |
594 |
} |
} |