You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2013/07/26 03:03:53 UTC

svn commit: r1507169 - in /commons/proper/lang/trunk/src: main/java/org/apache/commons/lang3/math/NumberUtils.java test/java/org/apache/commons/lang3/math/NumberUtilsTest.java

Author: sebb
Date: Fri Jul 26 01:03:52 2013
New Revision: 1507169

URL: http://svn.apache.org/r1507169
Log:
LANG-747 NumberUtils does not handle Long Hex numbers

Modified:
    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/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=1507169&r1=1507168&r2=1507169&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 Fri Jul 26 01:03:52 2013
@@ -464,11 +464,20 @@ public class NumberUtils {
             }
         }
         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);

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=1507169&r1=1507168&r2=1507169&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 Fri Jul 26 01:03:52 2013
@@ -246,6 +246,43 @@ public class NumberUtilsTest {
         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() {