This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new 5904c573f NumberUtils.createNumber(String): Float shortcut can bypass 
exact (#1635)
5904c573f is described below

commit 5904c573ffacaa5d8836ffc2b346f400c8901ed1
Author: Gary Gregory <[email protected]>
AuthorDate: Tue May 5 23:09:17 2026 -0400

    NumberUtils.createNumber(String): Float shortcut can bypass exact (#1635)
    
    decimal parsing
---
 .../org/apache/commons/lang3/math/NumberUtils.java |   3 +-
 .../apache/commons/lang3/math/NumberUtilsTest.java | 108 ++++++++-------------
 2 files changed, 41 insertions(+), 70 deletions(-)

diff --git a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java 
b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
index 26ea13121..d23d714b3 100644
--- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
+++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
@@ -501,8 +501,7 @@ public static Number createNumber(final String str) {
         try {
             final Float f = createFloat(str);
             final Double d = createDouble(str);
-            if (!f.isInfinite() && !(f.floatValue() == 0.0F && !isZero(mant, 
dec))
-                    && ((double) d.floatValue() == d.doubleValue() || 
f.toString().equals(d.toString()))) {
+            if (!f.isInfinite() && !(f.floatValue() == 0.0F && !isZero(mant, 
dec)) && f.toString().equals(d.toString())) {
                 return f;
             }
             if (!d.isInfinite() && !(d.doubleValue() == 0.0D && !isZero(mant, 
dec))) {
diff --git a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java 
b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
index 7d901a875..67a6fe43c 100644
--- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
@@ -447,8 +447,10 @@ void testConstructor() {
 
     @Test
     void testCreateBigDecimal() {
-        assertEquals(new BigDecimal("1234.5"), 
NumberUtils.createBigDecimal("1234.5"),
-            "createBigDecimal(String) failed");
+        final String string1 = "1234.5";
+        assertEquals(new BigDecimal(string1), 
NumberUtils.createBigDecimal(string1), "createBigDecimal(String) failed");
+        final String string2 = "0.100000001490116121";
+        assertEquals(new BigDecimal(string2), 
NumberUtils.createBigDecimal(string2));
         assertNull(NumberUtils.createBigDecimal(null), "createBigDecimal(null) 
failed");
         testCreateBigDecimalFailure("");
         testCreateBigDecimalFailure(" ");
@@ -507,7 +509,10 @@ protected void testCreateBigIntegerFailure(final String 
str) {
 
     @Test
     void testCreateDouble() {
-        assertEquals(Double.valueOf("1234.5"), 
NumberUtils.createDouble("1234.5"), "createDouble(String) failed");
+        final String string1 = "1234.5";
+        assertEquals(Double.valueOf(string1), 
NumberUtils.createDouble(string1), "createDouble(String) failed");
+        final String string2 = "0.100000001490116121";
+        assertEquals(Double.valueOf(string2), 
NumberUtils.createDouble(string2));
         assertNull(NumberUtils.createDouble(null), "createDouble(null) 
failed");
         testCreateDoubleFailure("");
         testCreateDoubleFailure(" ");
@@ -582,8 +587,7 @@ void testCreateNumber() {
         assertEquals(Double.valueOf("1234.5"), 
NumberUtils.createNumber("1234.5d"), "createNumber(String) 3 failed");
         assertEquals(Float.valueOf("1234.5"), 
NumberUtils.createNumber("1234.5F"), "createNumber(String) 4 failed");
         assertEquals(Float.valueOf("1234.5"), 
NumberUtils.createNumber("1234.5f"), "createNumber(String) 4 failed");
-        assertEquals(Long.valueOf(Integer.MAX_VALUE + 1L), 
NumberUtils.createNumber("" + (Integer.MAX_VALUE + 1L)),
-            "createNumber(String) 5 failed");
+        assertEquals(Long.valueOf(Integer.MAX_VALUE + 1L), 
NumberUtils.createNumber("" + (Integer.MAX_VALUE + 1L)), "createNumber(String) 
5 failed");
         assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345L"), 
"createNumber(String) 6 failed");
         assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345l"), 
"createNumber(String) 6 failed");
         assertEquals(Float.valueOf("-1234.5"), 
NumberUtils.createNumber("-1234.5"), "createNumber(String) 7 failed");
@@ -594,85 +598,52 @@ void testCreateNumber() {
         assertEquals(-0xFADE, NumberUtils.createNumber("-0Xfade").intValue(), 
"createNumber(String) 10b failed");
         assertEquals(Double.valueOf("1.1E200"), 
NumberUtils.createNumber("1.1E200"), "createNumber(String) 11 failed");
         assertEquals(Float.valueOf("1.1E20"), 
NumberUtils.createNumber("1.1E20"), "createNumber(String) 12 failed");
-        assertEquals(Double.valueOf("-1.1E200"), 
NumberUtils.createNumber("-1.1E200"),
-            "createNumber(String) 13 failed");
-        assertEquals(Double.valueOf("1.1E-200"), 
NumberUtils.createNumber("1.1E-200"),
-            "createNumber(String) 14 failed");
+        assertEquals(Double.valueOf("-1.1E200"), 
NumberUtils.createNumber("-1.1E200"), "createNumber(String) 13 failed");
+        assertEquals(Double.valueOf("1.1E-200"), 
NumberUtils.createNumber("1.1E-200"), "createNumber(String) 14 failed");
         assertNull(NumberUtils.createNumber(null), "createNumber(null) 
failed");
-        assertEquals(new BigInteger("12345678901234567890"), 
NumberUtils.createNumber("12345678901234567890L"),
-            "createNumber(String) failed");
-
-        assertEquals(new BigDecimal("1.1E-700"), 
NumberUtils.createNumber("1.1E-700F"),
-            "createNumber(String) 15 failed");
-
-        assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), 
NumberUtils.createNumber("10" + Integer.MAX_VALUE + "L"),
-            "createNumber(String) 16 failed");
-        assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), 
NumberUtils.createNumber("10" + Integer.MAX_VALUE),
-            "createNumber(String) 17 failed");
-        assertEquals(new BigInteger("10" + Long.MAX_VALUE), 
NumberUtils.createNumber("10" + Long.MAX_VALUE),
-            "createNumber(String) 18 failed");
-
+        assertEquals(new BigInteger("12345678901234567890"), 
NumberUtils.createNumber("12345678901234567890L"), "createNumber(String) 
failed");
+        assertEquals(new BigDecimal("1.1E-700"), 
NumberUtils.createNumber("1.1E-700F"), "createNumber(String) 15 failed");
+        assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), 
NumberUtils.createNumber("10" + Integer.MAX_VALUE + "L"), "createNumber(String) 
16 failed");
+        assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), 
NumberUtils.createNumber("10" + Integer.MAX_VALUE), "createNumber(String) 17 
failed");
+        assertEquals(new BigInteger("10" + Long.MAX_VALUE), 
NumberUtils.createNumber("10" + Long.MAX_VALUE), "createNumber(String) 18 
failed");
         // LANG-521
         assertEquals(Float.valueOf("2."), NumberUtils.createNumber("2."), 
"createNumber(String) LANG-521 failed");
-
         // LANG-638
         assertFalse(checkCreateNumber("1eE"), "createNumber(String) 
succeeded");
-
         // LANG-693
-        assertEquals(Double.valueOf(Double.MAX_VALUE), 
NumberUtils.createNumber("" + Double.MAX_VALUE),
-            "createNumber(String) LANG-693 failed");
-
+        assertEquals(Double.valueOf(Double.MAX_VALUE), 
NumberUtils.createNumber("" + Double.MAX_VALUE), "createNumber(String) LANG-693 
failed");
         // LANG-822
         // ensure that the underlying negative number would create a BigDecimal
         final Number bigNum = NumberUtils.createNumber("-1.1E-700F");
         assertNotNull(bigNum);
         assertEquals(BigDecimal.class, bigNum.getClass());
-
         // LANG-1018
-        assertEquals(Double.valueOf("-160952.54"), 
NumberUtils.createNumber("-160952.54"),
-            "createNumber(String) LANG-1018 failed");
+        assertEquals(Double.valueOf("-160952.54"), 
NumberUtils.createNumber("-160952.54"), "createNumber(String) LANG-1018 
failed");
         // LANG-1187
-        assertEquals(Double.valueOf("6264583.33"), 
NumberUtils.createNumber("6264583.33"),
-            "createNumber(String) LANG-1187 failed");
+        assertEquals(Double.valueOf("6264583.33"), 
NumberUtils.createNumber("6264583.33"), "createNumber(String) LANG-1187 
failed");
         // LANG-1215
-        assertEquals(Double.valueOf("193343.82"), 
NumberUtils.createNumber("193343.82"),
-            "createNumber(String) LANG-1215 failed");
+        assertEquals(Double.valueOf("193343.82"), 
NumberUtils.createNumber("193343.82"), "createNumber(String) LANG-1215 failed");
         // LANG-1060
-        assertEquals(Double.valueOf("001234.5678"), 
NumberUtils.createNumber("001234.5678"),
-            "createNumber(String) LANG-1060a failed");
-        assertEquals(Double.valueOf("+001234.5678"), 
NumberUtils.createNumber("+001234.5678"),
-            "createNumber(String) LANG-1060b failed");
-        assertEquals(Double.valueOf("-001234.5678"), 
NumberUtils.createNumber("-001234.5678"),
-            "createNumber(String) LANG-1060c failed");
-        assertEquals(Double.valueOf("0000.00000"), 
NumberUtils.createNumber("0000.00000d"),
-            "createNumber(String) LANG-1060d failed");
-        assertEquals(Float.valueOf("001234.56"), 
NumberUtils.createNumber("001234.56"),
-            "createNumber(String) LANG-1060e failed");
-        assertEquals(Float.valueOf("+001234.56"), 
NumberUtils.createNumber("+001234.56"),
-            "createNumber(String) LANG-1060f failed");
-        assertEquals(Float.valueOf("-001234.56"), 
NumberUtils.createNumber("-001234.56"),
-            "createNumber(String) LANG-1060g failed");
-        assertEquals(Float.valueOf("0000.10"), 
NumberUtils.createNumber("0000.10"),
-            "createNumber(String) LANG-1060h failed");
-        assertEquals(Float.valueOf("001.1E20"), 
NumberUtils.createNumber("001.1E20"),
-            "createNumber(String) LANG-1060i failed");
-        assertEquals(Float.valueOf("+001.1E20"), 
NumberUtils.createNumber("+001.1E20"),
-            "createNumber(String) LANG-1060j failed");
-        assertEquals(Float.valueOf("-001.1E20"), 
NumberUtils.createNumber("-001.1E20"),
-            "createNumber(String) LANG-1060k failed");
-        assertEquals(Double.valueOf("001.1E200"), 
NumberUtils.createNumber("001.1E200"),
-            "createNumber(String) LANG-1060l failed");
-        assertEquals(Double.valueOf("+001.1E200"), 
NumberUtils.createNumber("+001.1E200"),
-            "createNumber(String) LANG-1060m failed");
-        assertEquals(Double.valueOf("-001.1E200"), 
NumberUtils.createNumber("-001.1E200"),
-            "createNumber(String) LANG-1060n failed");
+        assertEquals(Double.valueOf("001234.5678"), 
NumberUtils.createNumber("001234.5678"), "createNumber(String) LANG-1060a 
failed");
+        assertEquals(Double.valueOf("+001234.5678"), 
NumberUtils.createNumber("+001234.5678"), "createNumber(String) LANG-1060b 
failed");
+        assertEquals(Double.valueOf("-001234.5678"), 
NumberUtils.createNumber("-001234.5678"), "createNumber(String) LANG-1060c 
failed");
+        assertEquals(Double.valueOf("0000.00000"), 
NumberUtils.createNumber("0000.00000d"), "createNumber(String) LANG-1060d 
failed");
+        assertEquals(Float.valueOf("001234.56"), 
NumberUtils.createNumber("001234.56"), "createNumber(String) LANG-1060e 
failed");
+        assertEquals(Float.valueOf("+001234.56"), 
NumberUtils.createNumber("+001234.56"), "createNumber(String) LANG-1060f 
failed");
+        assertEquals(Float.valueOf("-001234.56"), 
NumberUtils.createNumber("-001234.56"), "createNumber(String) LANG-1060g 
failed");
+        assertEquals(Float.valueOf("0000.10"), 
NumberUtils.createNumber("0000.10"), "createNumber(String) LANG-1060h failed");
+        assertEquals(Float.valueOf("001.1E20"), 
NumberUtils.createNumber("001.1E20"), "createNumber(String) LANG-1060i failed");
+        assertEquals(Float.valueOf("+001.1E20"), 
NumberUtils.createNumber("+001.1E20"), "createNumber(String) LANG-1060j 
failed");
+        assertEquals(Float.valueOf("-001.1E20"), 
NumberUtils.createNumber("-001.1E20"), "createNumber(String) LANG-1060k 
failed");
+        assertEquals(Double.valueOf("001.1E200"), 
NumberUtils.createNumber("001.1E200"), "createNumber(String) LANG-1060l 
failed");
+        assertEquals(Double.valueOf("+001.1E200"), 
NumberUtils.createNumber("+001.1E200"), "createNumber(String) LANG-1060m 
failed");
+        assertEquals(Double.valueOf("-001.1E200"), 
NumberUtils.createNumber("-001.1E200"), "createNumber(String) LANG-1060n 
failed");
         // LANG-1645
-        assertEquals(Integer.decode("+0xF"), NumberUtils.createNumber("+0xF"),
-            "createNumber(String) LANG-1645a failed");
-        assertEquals(Long.decode("+0xFFFFFFFF"), 
NumberUtils.createNumber("+0xFFFFFFFF"),
-            "createNumber(String) LANG-1645b failed");
-        assertEquals(new BigInteger("+FFFFFFFFFFFFFFFF", 16), 
NumberUtils.createNumber("+0xFFFFFFFFFFFFFFFF"),
-            "createNumber(String) LANG-1645c failed");
+        assertEquals(Integer.decode("+0xF"), NumberUtils.createNumber("+0xF"), 
"createNumber(String) LANG-1645a failed");
+        assertEquals(Long.decode("+0xFFFFFFFF"), 
NumberUtils.createNumber("+0xFFFFFFFF"), "createNumber(String) LANG-1645b 
failed");
+        assertEquals(new BigInteger("+FFFFFFFFFFFFFFFF", 16), 
NumberUtils.createNumber("+0xFFFFFFFFFFFFFFFF"), "createNumber(String) 
LANG-1645c failed");
+        // Map to a BigDecimal, not a Float.
+        assertEquals(new BigDecimal("0.100000001490116121"), 
NumberUtils.createNumber("0.100000001490116121"));
     }
 
     @Test
@@ -905,6 +876,7 @@ void testIsCreatable() {
         compareIsCreatableWithCreateNumber("1.0E-2147483648", false);
         compareIsCreatableWithCreateNumber("1E+999999999999999999999", false);
         compareIsCreatableWithCreateNumber("1E-999999999999999999999", false);
+        compareIsCreatableWithCreateNumber("0.100000001490116121", true);
     }
 
     @Test

Reply via email to