Repository: commons-lang Updated Branches: refs/heads/master 7fd021d82 -> d2fb3b086
LANG-1018: Fix precision loss on NumberUtils.createNumber(String) (closes #156) Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/8d6bc0ca Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/8d6bc0ca Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/8d6bc0ca Branch: refs/heads/master Commit: 8d6bc0ca625f3a1a98b486541fa613b2fac4b41c Parents: 7fd021d Author: Nick Manley <nickmanle...@outlook.com> Authored: Thu Jun 9 23:04:18 2016 -0500 Committer: pascalschumacher <pascalschumac...@gmx.net> Committed: Sun Jun 12 13:23:55 2016 +0200 ---------------------------------------------------------------------- .../apache/commons/lang3/math/NumberUtils.java | 26 ++++++++------------ .../commons/lang3/math/NumberUtilsTest.java | 4 +++ 2 files changed, 14 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-lang/blob/8d6bc0ca/src/main/java/org/apache/commons/lang3/math/NumberUtils.java ---------------------------------------------------------------------- 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 22dddf4..3d59057 100644 --- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java +++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java @@ -491,9 +491,7 @@ public class NumberUtils { // if both e and E are present, this is caught by the checks on expPos (which prevent IOOBE) // and the parsing which will detect if e or E appear in a number due to using the wrong offset - int numDecimals = 0; // Check required precision (LANG-693) if (decPos > -1) { // there is a decimal point - if (expPos > -1) { // there is an exponent if (expPos < decPos || expPos > str.length()) { // prevents double exponent causing IOOBE throw new NumberFormatException(str + " is not a valid number."); @@ -503,7 +501,6 @@ public class NumberUtils { dec = str.substring(decPos + 1); } mant = getMantissa(str, decPos); - numDecimals = dec.length(); // gets number of digits past the decimal to ensure no loss of precision for floating point numbers. } else { if (expPos > -1) { if (expPos > str.length()) { // prevents double exponent causing IOOBE @@ -599,26 +596,23 @@ public class NumberUtils { //Must be a Float, Double, BigDecimal final boolean allZeros = isAllZeros(mant) && isAllZeros(exp); try { - if(numDecimals <= 7){// If number has 7 or fewer digits past the decimal point then make it a float - final Float f = createFloat(str); - if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) { - return f; - } + final Float f = createFloat(str); + final Double d = createDouble(str); + if (!f.isInfinite() + && !(f.floatValue() == 0.0F && !allZeros) + && f.toString().equals(d.toString())) { + return f; } - } catch (final NumberFormatException nfe) { // NOPMD - // ignore the bad number - } - try { - if(numDecimals <= 16){// If number has between 8 and 16 digits past the decimal point then make it a double - final Double d = createDouble(str); - if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) { + if (!d.isInfinite() && !(d.doubleValue() == 0.0D && !allZeros)) { + final BigDecimal b = createBigDecimal(str); + if (b.compareTo(BigDecimal.valueOf(d)) == 0) { return d; } + return b; } } catch (final NumberFormatException nfe) { // NOPMD // ignore the bad number } - return createBigDecimal(str); } http://git-wip-us.apache.org/repos/asf/commons-lang/blob/8d6bc0ca/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java ---------------------------------------------------------------------- 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 236084b..e2143bd 100644 --- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java @@ -242,6 +242,10 @@ public class NumberUtilsTest { final Number bigNum = NumberUtils.createNumber("-1.1E-700F"); assertNotNull(bigNum); assertEquals(BigDecimal.class, bigNum.getClass()); + + // LANG-1018 + assertEquals("createNumber(String) LANG-1018 failed", + Double.valueOf("-160952.54"), NumberUtils.createNumber("-160952.54")); } @Test