106 |
*/ |
*/ |
107 |
public Integer(String s) |
public Integer(String s) |
108 |
{ |
{ |
109 |
value = parseInt(s, 10); |
value = parseInt(s, 10, false); |
110 |
} |
} |
111 |
|
|
112 |
/** |
/** |
130 |
// Use an array large enough for a binary number. |
// Use an array large enough for a binary number. |
131 |
char[] buffer = new char[33]; |
char[] buffer = new char[33]; |
132 |
int i = 33; |
int i = 33; |
133 |
boolean isNeg; |
boolean isNeg = false; |
134 |
if (num < 0) |
if (num < 0) |
135 |
{ |
{ |
136 |
isNeg = true; |
isNeg = true; |
138 |
|
|
139 |
// When the value is MIN_VALUE, it overflows when made positive |
// When the value is MIN_VALUE, it overflows when made positive |
140 |
if (num < 0) |
if (num < 0) |
141 |
{ |
return "" + MIN_VALUE; |
|
buffer[--i] = Character.forDigit(-(num + radix) % radix, radix); |
|
|
num = -(num / radix); |
|
|
} |
|
142 |
} |
} |
|
else |
|
|
isNeg = false; |
|
143 |
|
|
144 |
do |
do |
145 |
{ |
{ |
146 |
buffer[--i] = Character.forDigit(num % radix, radix); |
buffer[--i] = digits[num % radix]; |
147 |
num /= radix; |
num /= radix; |
148 |
} |
} |
149 |
while (num > 0); |
while (num > 0); |
224 |
*/ |
*/ |
225 |
public static int parseInt(String str, int radix) |
public static int parseInt(String str, int radix) |
226 |
{ |
{ |
227 |
final int len; |
return parseInt(str, radix, false); |
|
|
|
|
if (str == null) |
|
|
throw new NumberFormatException(); |
|
|
|
|
|
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 parseInt(str, index, len, isNeg, radix); |
|
228 |
} |
} |
229 |
|
|
230 |
/** |
/** |
239 |
*/ |
*/ |
240 |
public static int parseInt(String s) |
public static int parseInt(String s) |
241 |
{ |
{ |
242 |
return parseInt(s, 10); |
return parseInt(s, 10, false); |
243 |
} |
} |
244 |
|
|
245 |
/** |
/** |
255 |
*/ |
*/ |
256 |
public static Integer valueOf(String s, int radix) |
public static Integer valueOf(String s, int radix) |
257 |
{ |
{ |
258 |
return new Integer(parseInt(s, radix)); |
return new Integer(parseInt(s, radix, false)); |
259 |
} |
} |
260 |
|
|
261 |
/** |
/** |
271 |
*/ |
*/ |
272 |
public static Integer valueOf(String s) |
public static Integer valueOf(String s) |
273 |
{ |
{ |
274 |
return new Integer(parseInt(s, 10)); |
return new Integer(parseInt(s, 10, false)); |
275 |
} |
} |
276 |
|
|
277 |
/** |
/** |
418 |
*/ |
*/ |
419 |
public static Integer getInteger(String nm, Integer def) |
public static Integer getInteger(String nm, Integer def) |
420 |
{ |
{ |
421 |
String val = System.getProperty(nm); |
if (nm == null || "".equals(nm)) |
422 |
if (val == null) |
return def; |
423 |
|
nm = System.getProperty(nm); |
424 |
|
if (nm == null) |
425 |
return def; |
return def; |
426 |
try |
try |
427 |
{ |
{ |
428 |
return decode(val); |
return decode(nm); |
429 |
} |
} |
430 |
catch (NumberFormatException e) |
catch (NumberFormatException e) |
431 |
{ |
{ |
454 |
* <em>DecimalDigit</em>: |
* <em>DecimalDigit</em>: |
455 |
* <em>Character.digit(d, 16) has value 0 to 15</em> |
* <em>Character.digit(d, 16) has value 0 to 15</em> |
456 |
* </pre> |
* </pre> |
457 |
* Note that you cannot decode MIN_VALUE, as the specification requires |
* Finally, the value must be in the range <code>MIN_VALUE</code> to |
458 |
* that the digits be parsed before negating the result, but 2147483648 |
* <code>MAX_VALUE</code>, or an exception is thrown. |
|
* will not fit in an int. |
|
459 |
* |
* |
460 |
* @param s the <code>String</code> to interpret |
* @param s the <code>String</code> to interpret |
461 |
* @return the value of the String as an <code>Integer</code> |
* @return the value of the String as an <code>Integer</code> |
462 |
* @throws NumberFormatException if <code>s</code> cannot be parsed as a |
* @throws NumberFormatException if <code>s</code> cannot be parsed as a |
463 |
* <code>int</code> |
* <code>int</code> |
464 |
* @throws NullPointerException if s is null |
* @throws NullPointerException if <code>s</code> is null |
465 |
* @since 1.2 |
* @since 1.2 |
466 |
*/ |
*/ |
467 |
public static Integer decode(String str) |
public static Integer decode(String str) |
468 |
{ |
{ |
469 |
boolean isNeg = false; |
return new Integer(parseInt(str, 10, true)); |
|
int index = 0; |
|
|
int radix = 10; |
|
|
final int len; |
|
|
|
|
|
if (str == null || (len = str.length()) == 0) |
|
|
throw new NumberFormatException("string null or empty"); |
|
|
|
|
|
// Negative numbers are always radix 10. |
|
|
if (str.charAt(index) == '-') |
|
|
{ |
|
|
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 Integer(0); |
|
|
|
|
|
index++; |
|
|
if (str.charAt(index) == 'x' || str.charAt(index) == 'X') |
|
|
{ |
|
|
radix = 16; |
|
|
index++; |
|
|
} |
|
|
else |
|
|
radix = 8; |
|
|
} |
|
|
|
|
|
if (index >= len) |
|
|
throw new NumberFormatException("empty value"); |
|
|
|
|
|
return new Integer(parseInt(str, index, len, isNeg, radix)); |
|
470 |
} |
} |
471 |
|
|
472 |
/** |
/** |
511 |
private static String toUnsignedString(int num, int exp) |
private static String toUnsignedString(int num, int exp) |
512 |
{ |
{ |
513 |
// Use an array large enough for a binary number. |
// Use an array large enough for a binary number. |
514 |
int radix = 1 << exp; |
int mask = (1 << exp) - 1; |
|
int mask = radix - 1; |
|
515 |
char[] buffer = new char[32]; |
char[] buffer = new char[32]; |
516 |
int i = 32; |
int i = 32; |
517 |
do |
do |
518 |
{ |
{ |
519 |
buffer[--i] = Character.forDigit(num & mask, radix); |
buffer[--i] = digits[num & mask]; |
520 |
num = num >>> exp; |
num >>>= exp; |
521 |
} |
} |
522 |
while (num != 0); |
while (num != 0); |
523 |
|
|
525 |
} |
} |
526 |
|
|
527 |
/** |
/** |
528 |
* Helper for parsing ints. |
* Helper for parsing ints, used by Integer, Short, and Byte. |
529 |
* |
* |
530 |
* @param str the string to parse |
* @param str the string to parse |
531 |
* @param index the index to start at |
* @param radix the radix to use, must be 10 if decode is true |
532 |
* @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 |
|
533 |
* @return the parsed int value |
* @return the parsed int value |
534 |
* @throws NumberFormatException if there is an error |
* @throws NumberFormatException if there is an error |
535 |
|
* @throws NullPointerException if decode is true and str if null |
536 |
|
* @see #parseInt(String, int) |
537 |
|
* @see #decode(String) |
538 |
|
* @see Byte#parseInt(String, int) |
539 |
|
* @see Short#parseInt(String, int) |
540 |
*/ |
*/ |
541 |
private static int parseInt(String str, int index, int len, boolean isNeg, |
static int parseInt(String str, int radix, boolean decode) |
|
int radix) |
|
542 |
{ |
{ |
543 |
int val = 0; |
if (! decode && str == null) |
544 |
int digval; |
throw new NumberFormatException(); |
545 |
|
int index = 0; |
546 |
int max = MAX_VALUE / radix; |
int len = str.length(); |
547 |
// We can't directly write `max = (MAX_VALUE + 1) / radix'. |
boolean isNeg = false; |
548 |
// So instead we fake it. |
if (len == 0) |
549 |
if (isNeg && MAX_VALUE % radix == radix - 1) |
throw new NumberFormatException(); |
550 |
++max; |
int ch = str.charAt(index); |
551 |
|
if (ch == '-') |
|
for ( ; index < len; index++) |
|
552 |
{ |
{ |
553 |
if (val < 0 || val > max) |
if (len == 1) |
|
throw new NumberFormatException(); |
|
|
|
|
|
if ((digval = Character.digit(str.charAt(index), radix)) < 0) |
|
554 |
throw new NumberFormatException(); |
throw new NumberFormatException(); |
555 |
|
isNeg = true; |
556 |
// Throw an exception for overflow if result is negative. |
ch = str.charAt(++index); |
557 |
// However, we special-case the most negative value. |
} |
558 |
val = val * radix + digval; |
if (decode) |
559 |
if (val < 0 && (! isNeg || val != MIN_VALUE)) |
{ |
560 |
|
if (ch == '0') |
561 |
|
{ |
562 |
|
if (++index == len) |
563 |
|
return 0; |
564 |
|
if ((str.charAt(index) & ~('x' ^ 'X')) == 'X') |
565 |
|
{ |
566 |
|
radix = 16; |
567 |
|
index++; |
568 |
|
} |
569 |
|
else |
570 |
|
radix = 8; |
571 |
|
} |
572 |
|
else if (ch == '#') |
573 |
|
{ |
574 |
|
radix = 16; |
575 |
|
index++; |
576 |
|
} |
577 |
|
} |
578 |
|
if (index == len) |
579 |
|
throw new NumberFormatException(); |
580 |
|
int val = 0; |
581 |
|
while (index < len) |
582 |
|
{ |
583 |
|
ch = Character.digit(str.charAt(index++), radix); |
584 |
|
val = val * radix + ch; |
585 |
|
if (ch < 0 || (val < 0 && (index < len || ! isNeg |
586 |
|
|| val != MIN_VALUE))) |
587 |
throw new NumberFormatException(); |
throw new NumberFormatException(); |
588 |
} |
} |
|
|
|
589 |
return isNeg ? -val : val; |
return isNeg ? -val : val; |
590 |
} |
} |
591 |
} |
} |