LANG-693 Method createNumber from NumberUtils doesn't work for floating point numbers other than Float
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1484263 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
64cfee77e3
commit
8a1042959d
|
@ -22,6 +22,7 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<release version="3.2" date="TBA" description="Next release">
|
<release version="3.2" date="TBA" description="Next release">
|
||||||
|
<action issue="LANG-693" type="fix" due-to="Calvin Echols">Method createNumber from NumberUtils doesn't work for floating point numbers other than Float</action>
|
||||||
<action issue="LANG-887" type="fix">FastDateFormat does not use the locale specific cache correctly</action>
|
<action issue="LANG-887" type="fix">FastDateFormat does not use the locale specific cache correctly</action>
|
||||||
<action issue="LANG-884" type="update">Simplify FastDateFormat; eliminate boxing</action>
|
<action issue="LANG-884" type="update">Simplify FastDateFormat; eliminate boxing</action>
|
||||||
<action issue="LANG-882" type="update">LookupTranslator now works with implementations of CharSequence other than String</action>
|
<action issue="LANG-882" type="update">LookupTranslator now works with implementations of CharSequence other than String</action>
|
||||||
|
|
|
@ -482,6 +482,7 @@ public static Number createNumber(final String str) throws NumberFormatException
|
||||||
// if both e and E are present, this is caught by the checks on expPos (which prevent IOOBE)
|
// 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
|
// 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 (decPos > -1) { // there is a decimal point
|
||||||
|
|
||||||
if (expPos > -1) { // there is an exponent
|
if (expPos > -1) { // there is an exponent
|
||||||
|
@ -493,6 +494,7 @@ public static Number createNumber(final String str) throws NumberFormatException
|
||||||
dec = str.substring(decPos + 1);
|
dec = str.substring(decPos + 1);
|
||||||
}
|
}
|
||||||
mant = str.substring(0, decPos);
|
mant = str.substring(0, decPos);
|
||||||
|
numDecimals = dec.length(); // gets number of digits past the decimal to ensure no loss of precision for floating point numbers.
|
||||||
} else {
|
} else {
|
||||||
if (expPos > -1) {
|
if (expPos > -1) {
|
||||||
if (expPos > str.length()) { // prevents double exponent causing IOOBE
|
if (expPos > str.length()) { // prevents double exponent causing IOOBE
|
||||||
|
@ -588,17 +590,21 @@ public static Number createNumber(final String str) throws NumberFormatException
|
||||||
//Must be a Float, Double, BigDecimal
|
//Must be a Float, Double, BigDecimal
|
||||||
final boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
|
final boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
|
||||||
try {
|
try {
|
||||||
final Float f = createFloat(str);
|
if(numDecimals <= 7){// If number has 7 or fewer digits past the decimal point then make it a float
|
||||||
if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
|
final Float f = createFloat(str);
|
||||||
return f;
|
if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (final NumberFormatException nfe) { // NOPMD
|
} catch (final NumberFormatException nfe) { // NOPMD
|
||||||
// ignore the bad number
|
// ignore the bad number
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final Double d = createDouble(str);
|
if(numDecimals <= 16){// If number has between 8 and 16 digits past the decimal point then make it a double
|
||||||
if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) {
|
final Double d = createDouble(str);
|
||||||
return d;
|
if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (final NumberFormatException nfe) { // NOPMD
|
} catch (final NumberFormatException nfe) { // NOPMD
|
||||||
// ignore the bad number
|
// ignore the bad number
|
||||||
|
|
|
@ -115,7 +115,20 @@ public void testToFloatStringF() {
|
||||||
assertTrue("toFloat(String,int) 1 failed", NumberUtils.toFloat("1.2345", 5.1f) == 1.2345f);
|
assertTrue("toFloat(String,int) 1 failed", NumberUtils.toFloat("1.2345", 5.1f) == 1.2345f);
|
||||||
assertTrue("toFloat(String,int) 2 failed", NumberUtils.toFloat("a", 5.0f) == 5.0f);
|
assertTrue("toFloat(String,int) 2 failed", NumberUtils.toFloat("a", 5.0f) == 5.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {(@link NumberUtils#createNumber(String)}
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testStringCreateNumberEnsureNoPrecisionLoss(){
|
||||||
|
String shouldBeFloat = "1.23";
|
||||||
|
String shouldBeDouble = "3.40282354e+38";
|
||||||
|
String shouldBeBigDecimal = "1.797693134862315759e+308";
|
||||||
|
|
||||||
|
assertTrue(NumberUtils.createNumber(shouldBeFloat) instanceof Float);
|
||||||
|
assertTrue(NumberUtils.createNumber(shouldBeDouble) instanceof Double);
|
||||||
|
assertTrue(NumberUtils.createNumber(shouldBeBigDecimal) instanceof BigDecimal);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Test for {@link NumberUtils#toDouble(String)}.
|
* Test for {@link NumberUtils#toDouble(String)}.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue