From 5ddff03a262edd419bf3a3821448da56387e96f7 Mon Sep 17 00:00:00 2001 From: d0b02bt Date: Mon, 14 Dec 2020 15:46:37 +0530 Subject: [PATCH 1/4] LANG-1444 NumberUtils.createNumber(), BigDecimal for decimal fractions tending to zero --- .../org/apache/commons/lang3/math/NumberUtils.java | 5 +++-- .../apache/commons/lang3/math/NumberUtilsTest.java | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 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 c984dbf25e9..7b3d2e9244a 100644 --- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java +++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java @@ -798,13 +798,14 @@ public static Number createNumber(final String str) { try { final Float f = createFloat(str); final Double d = createDouble(str); + final BigDecimal b = createBigDecimal(str); if (!f.isInfinite() && !(f.floatValue() == 0.0F && !allZeros) - && f.toString().equals(d.toString())) { + && f.toString().equals(d.toString()) + && (f.toString().equals(b.stripTrailingZeros().toString().replace("+","")) || b.compareTo(BigDecimal.valueOf(f)) == 0)) { return f; } if (!d.isInfinite() && !(d.doubleValue() == 0.0D && !allZeros)) { - final BigDecimal b = createBigDecimal(str); if (b.compareTo(BigDecimal.valueOf(d.doubleValue())) == 0) { return d; } 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 ec62278f833..8933682c853 100644 --- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java @@ -642,6 +642,17 @@ public void testCreateNumberMagnitude() { assertEquals(new BigInteger("1777777777777777777777", 8), NumberUtils.createNumber("01777777777777777777777")); } + @Test + //LANG-1444 + void testCheckDataTypeForFloatDoubleBigDecimal() { + assertEquals(NumberUtils.createNumber("1.1").getClass().getName(),Float.class.getName()); + assertEquals(NumberUtils.createNumber("1.0000001").getClass().getName(),Float.class.getName()); + assertEquals(NumberUtils.createNumber("1.000000001").getClass().getName(),Double.class.getName()); + assertEquals(NumberUtils.createNumber("1.000000000000001").getClass().getName(),Double.class.getName()); + assertEquals(NumberUtils.createNumber("1.00000000000000001").getClass().getName(),BigDecimal.class.getName()); + assertEquals(NumberUtils.createNumber("1.00000000000000000000001").getClass().getName(),BigDecimal.class.getName()); + } + /** * Tests isCreatable(String) and tests that createNumber(String) returns a valid number iff isCreatable(String) * returns false. From 64e1efc9544745cde3b9b9946a5e237a3138c3af Mon Sep 17 00:00:00 2001 From: d0b02bt Date: Wed, 16 Dec 2020 12:36:13 +0530 Subject: [PATCH 2/4] LANG-1444 adding white spaces for , --- .../org/apache/commons/lang3/math/NumberUtils.java | 2 +- .../apache/commons/lang3/math/NumberUtilsTest.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 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 7b3d2e9244a..a986ee6f1e4 100644 --- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java +++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java @@ -802,7 +802,7 @@ public static Number createNumber(final String str) { if (!f.isInfinite() && !(f.floatValue() == 0.0F && !allZeros) && f.toString().equals(d.toString()) - && (f.toString().equals(b.stripTrailingZeros().toString().replace("+","")) || b.compareTo(BigDecimal.valueOf(f)) == 0)) { + && (f.toString().equals(b.stripTrailingZeros().toString().replace("+" , "")) || b.compareTo(BigDecimal.valueOf(f)) == 0)) { return f; } if (!d.isInfinite() && !(d.doubleValue() == 0.0D && !allZeros)) { 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 8933682c853..c63e4b6679c 100644 --- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java @@ -645,12 +645,12 @@ public void testCreateNumberMagnitude() { @Test //LANG-1444 void testCheckDataTypeForFloatDoubleBigDecimal() { - assertEquals(NumberUtils.createNumber("1.1").getClass().getName(),Float.class.getName()); - assertEquals(NumberUtils.createNumber("1.0000001").getClass().getName(),Float.class.getName()); - assertEquals(NumberUtils.createNumber("1.000000001").getClass().getName(),Double.class.getName()); - assertEquals(NumberUtils.createNumber("1.000000000000001").getClass().getName(),Double.class.getName()); - assertEquals(NumberUtils.createNumber("1.00000000000000001").getClass().getName(),BigDecimal.class.getName()); - assertEquals(NumberUtils.createNumber("1.00000000000000000000001").getClass().getName(),BigDecimal.class.getName()); + assertEquals(NumberUtils.createNumber("1.1").getClass().getName() , Float.class.getName()); + assertEquals(NumberUtils.createNumber("1.0000001").getClass().getName() , Float.class.getName()); + assertEquals(NumberUtils.createNumber("1.000000001").getClass().getName() , Double.class.getName()); + assertEquals(NumberUtils.createNumber("1.000000000000001").getClass().getName() , Double.class.getName()); + assertEquals(NumberUtils.createNumber("1.00000000000000001").getClass().getName() , BigDecimal.class.getName()); + assertEquals(NumberUtils.createNumber("1.00000000000000000000001").getClass().getName() , BigDecimal.class.getName()); } /** From 8f0382441504cc4d0a01efc33b14d130918acfd1 Mon Sep 17 00:00:00 2001 From: d0b02bt Date: Wed, 16 Dec 2020 12:42:51 +0530 Subject: [PATCH 3/4] LANG-1444 adding white spaces for , --- .../org/apache/commons/lang3/math/NumberUtils.java | 2 +- .../apache/commons/lang3/math/NumberUtilsTest.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 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 a986ee6f1e4..f17afb22458 100644 --- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java +++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java @@ -802,7 +802,7 @@ public static Number createNumber(final String str) { if (!f.isInfinite() && !(f.floatValue() == 0.0F && !allZeros) && f.toString().equals(d.toString()) - && (f.toString().equals(b.stripTrailingZeros().toString().replace("+" , "")) || b.compareTo(BigDecimal.valueOf(f)) == 0)) { + && (f.toString().equals(b.stripTrailingZeros().toString().replace("+", "")) || b.compareTo(BigDecimal.valueOf(f)) == 0)) { return f; } if (!d.isInfinite() && !(d.doubleValue() == 0.0D && !allZeros)) { 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 c63e4b6679c..8b599d7f244 100644 --- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java @@ -645,12 +645,12 @@ public void testCreateNumberMagnitude() { @Test //LANG-1444 void testCheckDataTypeForFloatDoubleBigDecimal() { - assertEquals(NumberUtils.createNumber("1.1").getClass().getName() , Float.class.getName()); - assertEquals(NumberUtils.createNumber("1.0000001").getClass().getName() , Float.class.getName()); - assertEquals(NumberUtils.createNumber("1.000000001").getClass().getName() , Double.class.getName()); - assertEquals(NumberUtils.createNumber("1.000000000000001").getClass().getName() , Double.class.getName()); - assertEquals(NumberUtils.createNumber("1.00000000000000001").getClass().getName() , BigDecimal.class.getName()); - assertEquals(NumberUtils.createNumber("1.00000000000000000000001").getClass().getName() , BigDecimal.class.getName()); + assertEquals(NumberUtils.createNumber("1.1").getClass().getName(), Float.class.getName()); + assertEquals(NumberUtils.createNumber("1.0000001").getClass().getName(), Float.class.getName()); + assertEquals(NumberUtils.createNumber("1.000000001").getClass().getName(), Double.class.getName()); + assertEquals(NumberUtils.createNumber("1.000000000000001").getClass().getName(), Double.class.getName()); + assertEquals(NumberUtils.createNumber("1.00000000000000001").getClass().getName(), BigDecimal.class.getName()); + assertEquals(NumberUtils.createNumber("1.00000000000000000000001").getClass().getName(), BigDecimal.class.getName()); } /** From 548c4126dae9dd5256ad831ac6fb382b93add158 Mon Sep 17 00:00:00 2001 From: d0b02bt Date: Fri, 26 Feb 2021 15:29:21 +0530 Subject: [PATCH 4/4] LANG-1444 added test cases to ensure precision is not lost --- .../org/apache/commons/lang3/math/NumberUtilsTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 8b599d7f244..cfa7eb2e29a 100644 --- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java @@ -653,6 +653,16 @@ void testCheckDataTypeForFloatDoubleBigDecimal() { assertEquals(NumberUtils.createNumber("1.00000000000000000000001").getClass().getName(), BigDecimal.class.getName()); } + @Test + void testCheckPrecisionNotLostFloatDoubleBigDecimal() { + assertEquals(NumberUtils.createNumber("1.1"), Float.valueOf("1.1")); + assertEquals(NumberUtils.createNumber("1.0000001"), Float.valueOf("1.0000001")); + assertEquals(NumberUtils.createNumber("1.000000001"), Double.valueOf("1.000000001")); + assertEquals(NumberUtils.createNumber("1.000000000000001"), Double.valueOf("1.000000000000001")); + assertEquals(NumberUtils.createNumber("1.00000000000000001"), new BigDecimal("1.00000000000000001")); + assertEquals(NumberUtils.createNumber("1.00000000000000000000001"), new BigDecimal("1.00000000000000000000001")); + } + /** * Tests isCreatable(String) and tests that createNumber(String) returns a valid number iff isCreatable(String) * returns false.