Author: sebb
Date: Tue Nov 13 01:39:40 2012
New Revision: 1408537

URL: http://svn.apache.org/viewvc?rev=1408537&view=rev
Log:
LANG-854 NumberUtils#createNumber - does not allow for hex numbers to be larger 
than Long

Modified:
    commons/proper/lang/trunk/src/changes/changes.xml
    
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
    
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java

Modified: commons/proper/lang/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/changes/changes.xml?rev=1408537&r1=1408536&r2=1408537&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/changes/changes.xml (original)
+++ commons/proper/lang/trunk/src/changes/changes.xml Tue Nov 13 01:39:40 2012
@@ -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>

Modified: 
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
URL: 
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/math/NumberUtils.java?rev=1408537&r1=1408536&r2=1408537&view=diff
==============================================================================
--- 
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
 (original)
+++ 
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
 Tue Nov 13 01:39:40 2012
@@ -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;

Modified: 
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java?rev=1408537&r1=1408536&r2=1408537&view=diff
==============================================================================
--- 
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
 (original)
+++ 
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
 Tue Nov 13 01:39:40 2012
@@ -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


Reply via email to