LANG-854 NumberUtils#createNumber - does not allow for hex numbers to be larger than Long

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1408537 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastian Bazley 2012-11-13 01:39:40 +00:00
parent c1f9320476
commit d844d1eb5e
3 changed files with 31 additions and 6 deletions

View File

@ -23,6 +23,7 @@
<release version="3.2" date="TBA" description="Next release">
<action issue="LANG-855" type="add">NumberUtils#createBigInteger does not allow for hex and octal numbers</action>
<action issue="LANG-854" type="add">NumberUtils#createNumber - does not allow for hex numbers to be larger than Long</action>
<action issue="LANG-853" type="add">StringUtils join APIs for primitives</action>
<action issue="LANG-849" type="fix">FastDateFormat and FastDatePrinter generates Date objects wastefully</action>
<action issue="LANG-845" type="fix">Spelling fixes</action>

View File

@ -448,17 +448,26 @@ public class NumberUtils {
}
if (StringUtils.isBlank(str)) {
throw new NumberFormatException("A blank string is not a valid number");
}
if (str.startsWith("0x") || str.startsWith("-0x") || str.startsWith("0X") || str.startsWith("-0X")) {
int hexDigits = str.length() - 2; // drop 0x
if (str.startsWith("-")) { // drop -
hexDigits--;
}
// Need to deal with all possible hex prefixes here
final String[] hex_prefixes = {"0x", "0X", "-0x", "-0X", "#", "-#"};
int pfxLen = 0;
for(String pfx : hex_prefixes) {
if (str.startsWith(pfx)) {
pfxLen += pfx.length();
break;
}
}
if (pfxLen > 0) {
int hexDigits = str.length() - pfxLen;
if (hexDigits > 16) { // too many for Long
return createBigInteger(str);
}
if (hexDigits > 8) { // too many for an int
return createLong(str);
}
return createInteger(str);
}
}
char lastChar = str.charAt(str.length() - 1);
String mant;
String dec;

View File

@ -257,6 +257,21 @@ public class NumberUtilsTest {
assertEquals(Double.class, NumberUtils.createNumber("1.7976931348623157e+308").getClass());
// Test with +2 in final digit (+1 does not cause roll-over to BigDecimal)
assertEquals(BigDecimal.class, NumberUtils.createNumber("1.7976931348623159e+308").getClass());
assertEquals(Integer.class, NumberUtils.createNumber("0x12345678").getClass());
assertEquals(Long.class, NumberUtils.createNumber("0x123456789").getClass());
assertEquals(Long.class, NumberUtils.createNumber("0x7fffffffffffffff").getClass());
assertEquals(BigInteger.class, NumberUtils.createNumber("0x7fffffffffffffff0").getClass());
assertEquals(Long.class, NumberUtils.createNumber("#7fffffffffffffff").getClass());
assertEquals(BigInteger.class, NumberUtils.createNumber("#7fffffffffffffff0").getClass());
assertEquals(Integer.class, NumberUtils.createNumber("017777777777").getClass()); // 31 bits
assertEquals(Long.class, NumberUtils.createNumber("037777777777").getClass()); // 32 bits
assertEquals(Long.class, NumberUtils.createNumber("0777777777777777777777").getClass()); // 63 bits
assertEquals(BigInteger.class, NumberUtils.createNumber("01777777777777777777777").getClass());// 64 bits
}
@Test