LANG-747 NumberUtils does not handle Long Hex numbers

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1507169 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastian Bazley 2013-07-26 01:03:52 +00:00
parent 396afc3e46
commit d1a45e9738
2 changed files with 48 additions and 2 deletions

View File

@ -464,11 +464,20 @@ public static Number createNumber(final String str) throws NumberFormatException
}
}
if (pfxLen > 0) { // we have a hex number
char firstSigDigit = 0; // strip leading zeroes
for(int i = pfxLen; i < str.length(); i++) {
firstSigDigit = str.charAt(i);
if (firstSigDigit == '0') { // count leading zeroes
pfxLen++;
} else {
break;
}
}
final int hexDigits = str.length() - pfxLen;
if (hexDigits > 16) { // too many for Long
if (hexDigits > 16 || (hexDigits == 16 && firstSigDigit > '7')) { // too many for Long
return createBigInteger(str);
}
if (hexDigits > 8) { // too many for an int
if (hexDigits > 8 || (hexDigits == 8 && firstSigDigit > '7')) { // too many for an int
return createLong(str);
}
return createInteger(str);

View File

@ -246,6 +246,43 @@ public void testCreateNumber() {
assertEquals(BigDecimal.class, bigNum.getClass());
}
@Test
public void TestLang747() {
assertEquals(Integer.valueOf(0x8000), NumberUtils.createNumber("0x8000"));
assertEquals(Integer.valueOf(0x80000), NumberUtils.createNumber("0x80000"));
assertEquals(Integer.valueOf(0x800000), NumberUtils.createNumber("0x800000"));
assertEquals(Integer.valueOf(0x8000000), NumberUtils.createNumber("0x8000000"));
assertEquals(Integer.valueOf(0x7FFFFFFF), NumberUtils.createNumber("0x7FFFFFFF"));
assertEquals(Long.valueOf(0x80000000L), NumberUtils.createNumber("0x80000000"));
assertEquals(Long.valueOf(0xFFFFFFFFL), NumberUtils.createNumber("0xFFFFFFFF"));
// Leading zero tests
assertEquals(Integer.valueOf(0x8000000), NumberUtils.createNumber("0x08000000"));
assertEquals(Integer.valueOf(0x7FFFFFFF), NumberUtils.createNumber("0x007FFFFFFF"));
assertEquals(Long.valueOf(0x80000000L), NumberUtils.createNumber("0x080000000"));
assertEquals(Long.valueOf(0xFFFFFFFFL), NumberUtils.createNumber("0x00FFFFFFFF"));
assertEquals(Long.valueOf(0x800000000L), NumberUtils.createNumber("0x800000000"));
assertEquals(Long.valueOf(0x8000000000L), NumberUtils.createNumber("0x8000000000"));
assertEquals(Long.valueOf(0x80000000000L), NumberUtils.createNumber("0x80000000000"));
assertEquals(Long.valueOf(0x800000000000L), NumberUtils.createNumber("0x800000000000"));
assertEquals(Long.valueOf(0x8000000000000L), NumberUtils.createNumber("0x8000000000000"));
assertEquals(Long.valueOf(0x80000000000000L), NumberUtils.createNumber("0x80000000000000"));
assertEquals(Long.valueOf(0x800000000000000L), NumberUtils.createNumber("0x800000000000000"));
assertEquals(Long.valueOf(0x7FFFFFFFFFFFFFFFL), NumberUtils.createNumber("0x7FFFFFFFFFFFFFFF"));
// N.B. Cannot use a hex constant such as 0x8000000000000000L here as that is interpreted as a negative long
assertEquals(new BigInteger("8000000000000000", 16), NumberUtils.createNumber("0x8000000000000000"));
assertEquals(new BigInteger("FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("0xFFFFFFFFFFFFFFFF"));
// Leading zero tests
assertEquals(Long.valueOf(0x80000000000000L), NumberUtils.createNumber("0x00080000000000000"));
assertEquals(Long.valueOf(0x800000000000000L), NumberUtils.createNumber("0x0800000000000000"));
assertEquals(Long.valueOf(0x7FFFFFFFFFFFFFFFL), NumberUtils.createNumber("0x07FFFFFFFFFFFFFFF"));
// N.B. Cannot use a hex constant such as 0x8000000000000000L here as that is interpreted as a negative long
assertEquals(new BigInteger("8000000000000000", 16), NumberUtils.createNumber("0x00008000000000000000"));
assertEquals(new BigInteger("FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("0x0FFFFFFFFFFFFFFFF"));
}
@Test(expected=NumberFormatException.class)
// Check that the code fails to create a valid number when preceeded by -- rather than -
public void testCreateNumberFailure_1() {