Skip to content

Commit 5904c57

Browse files
authored
NumberUtils.createNumber(String): Float shortcut can bypass exact (#1635)
decimal parsing
1 parent 1dd7cb1 commit 5904c57

2 files changed

Lines changed: 41 additions & 70 deletions

File tree

src/main/java/org/apache/commons/lang3/math/NumberUtils.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,7 @@ public static Number createNumber(final String str) {
501501
try {
502502
final Float f = createFloat(str);
503503
final Double d = createDouble(str);
504-
if (!f.isInfinite() && !(f.floatValue() == 0.0F && !isZero(mant, dec))
505-
&& ((double) d.floatValue() == d.doubleValue() || f.toString().equals(d.toString()))) {
504+
if (!f.isInfinite() && !(f.floatValue() == 0.0F && !isZero(mant, dec)) && f.toString().equals(d.toString())) {
506505
return f;
507506
}
508507
if (!d.isInfinite() && !(d.doubleValue() == 0.0D && !isZero(mant, dec))) {

src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java

Lines changed: 40 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,10 @@ void testConstructor() {
447447

448448
@Test
449449
void testCreateBigDecimal() {
450-
assertEquals(new BigDecimal("1234.5"), NumberUtils.createBigDecimal("1234.5"),
451-
"createBigDecimal(String) failed");
450+
final String string1 = "1234.5";
451+
assertEquals(new BigDecimal(string1), NumberUtils.createBigDecimal(string1), "createBigDecimal(String) failed");
452+
final String string2 = "0.100000001490116121";
453+
assertEquals(new BigDecimal(string2), NumberUtils.createBigDecimal(string2));
452454
assertNull(NumberUtils.createBigDecimal(null), "createBigDecimal(null) failed");
453455
testCreateBigDecimalFailure("");
454456
testCreateBigDecimalFailure(" ");
@@ -507,7 +509,10 @@ protected void testCreateBigIntegerFailure(final String str) {
507509

508510
@Test
509511
void testCreateDouble() {
510-
assertEquals(Double.valueOf("1234.5"), NumberUtils.createDouble("1234.5"), "createDouble(String) failed");
512+
final String string1 = "1234.5";
513+
assertEquals(Double.valueOf(string1), NumberUtils.createDouble(string1), "createDouble(String) failed");
514+
final String string2 = "0.100000001490116121";
515+
assertEquals(Double.valueOf(string2), NumberUtils.createDouble(string2));
511516
assertNull(NumberUtils.createDouble(null), "createDouble(null) failed");
512517
testCreateDoubleFailure("");
513518
testCreateDoubleFailure(" ");
@@ -582,8 +587,7 @@ void testCreateNumber() {
582587
assertEquals(Double.valueOf("1234.5"), NumberUtils.createNumber("1234.5d"), "createNumber(String) 3 failed");
583588
assertEquals(Float.valueOf("1234.5"), NumberUtils.createNumber("1234.5F"), "createNumber(String) 4 failed");
584589
assertEquals(Float.valueOf("1234.5"), NumberUtils.createNumber("1234.5f"), "createNumber(String) 4 failed");
585-
assertEquals(Long.valueOf(Integer.MAX_VALUE + 1L), NumberUtils.createNumber("" + (Integer.MAX_VALUE + 1L)),
586-
"createNumber(String) 5 failed");
590+
assertEquals(Long.valueOf(Integer.MAX_VALUE + 1L), NumberUtils.createNumber("" + (Integer.MAX_VALUE + 1L)), "createNumber(String) 5 failed");
587591
assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345L"), "createNumber(String) 6 failed");
588592
assertEquals(Long.valueOf(12345), NumberUtils.createNumber("12345l"), "createNumber(String) 6 failed");
589593
assertEquals(Float.valueOf("-1234.5"), NumberUtils.createNumber("-1234.5"), "createNumber(String) 7 failed");
@@ -594,85 +598,52 @@ void testCreateNumber() {
594598
assertEquals(-0xFADE, NumberUtils.createNumber("-0Xfade").intValue(), "createNumber(String) 10b failed");
595599
assertEquals(Double.valueOf("1.1E200"), NumberUtils.createNumber("1.1E200"), "createNumber(String) 11 failed");
596600
assertEquals(Float.valueOf("1.1E20"), NumberUtils.createNumber("1.1E20"), "createNumber(String) 12 failed");
597-
assertEquals(Double.valueOf("-1.1E200"), NumberUtils.createNumber("-1.1E200"),
598-
"createNumber(String) 13 failed");
599-
assertEquals(Double.valueOf("1.1E-200"), NumberUtils.createNumber("1.1E-200"),
600-
"createNumber(String) 14 failed");
601+
assertEquals(Double.valueOf("-1.1E200"), NumberUtils.createNumber("-1.1E200"), "createNumber(String) 13 failed");
602+
assertEquals(Double.valueOf("1.1E-200"), NumberUtils.createNumber("1.1E-200"), "createNumber(String) 14 failed");
601603
assertNull(NumberUtils.createNumber(null), "createNumber(null) failed");
602-
assertEquals(new BigInteger("12345678901234567890"), NumberUtils.createNumber("12345678901234567890L"),
603-
"createNumber(String) failed");
604-
605-
assertEquals(new BigDecimal("1.1E-700"), NumberUtils.createNumber("1.1E-700F"),
606-
"createNumber(String) 15 failed");
607-
608-
assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), NumberUtils.createNumber("10" + Integer.MAX_VALUE + "L"),
609-
"createNumber(String) 16 failed");
610-
assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), NumberUtils.createNumber("10" + Integer.MAX_VALUE),
611-
"createNumber(String) 17 failed");
612-
assertEquals(new BigInteger("10" + Long.MAX_VALUE), NumberUtils.createNumber("10" + Long.MAX_VALUE),
613-
"createNumber(String) 18 failed");
614-
604+
assertEquals(new BigInteger("12345678901234567890"), NumberUtils.createNumber("12345678901234567890L"), "createNumber(String) failed");
605+
assertEquals(new BigDecimal("1.1E-700"), NumberUtils.createNumber("1.1E-700F"), "createNumber(String) 15 failed");
606+
assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), NumberUtils.createNumber("10" + Integer.MAX_VALUE + "L"), "createNumber(String) 16 failed");
607+
assertEquals(Long.valueOf("10" + Integer.MAX_VALUE), NumberUtils.createNumber("10" + Integer.MAX_VALUE), "createNumber(String) 17 failed");
608+
assertEquals(new BigInteger("10" + Long.MAX_VALUE), NumberUtils.createNumber("10" + Long.MAX_VALUE), "createNumber(String) 18 failed");
615609
// LANG-521
616610
assertEquals(Float.valueOf("2."), NumberUtils.createNumber("2."), "createNumber(String) LANG-521 failed");
617-
618611
// LANG-638
619612
assertFalse(checkCreateNumber("1eE"), "createNumber(String) succeeded");
620-
621613
// LANG-693
622-
assertEquals(Double.valueOf(Double.MAX_VALUE), NumberUtils.createNumber("" + Double.MAX_VALUE),
623-
"createNumber(String) LANG-693 failed");
624-
614+
assertEquals(Double.valueOf(Double.MAX_VALUE), NumberUtils.createNumber("" + Double.MAX_VALUE), "createNumber(String) LANG-693 failed");
625615
// LANG-822
626616
// ensure that the underlying negative number would create a BigDecimal
627617
final Number bigNum = NumberUtils.createNumber("-1.1E-700F");
628618
assertNotNull(bigNum);
629619
assertEquals(BigDecimal.class, bigNum.getClass());
630-
631620
// LANG-1018
632-
assertEquals(Double.valueOf("-160952.54"), NumberUtils.createNumber("-160952.54"),
633-
"createNumber(String) LANG-1018 failed");
621+
assertEquals(Double.valueOf("-160952.54"), NumberUtils.createNumber("-160952.54"), "createNumber(String) LANG-1018 failed");
634622
// LANG-1187
635-
assertEquals(Double.valueOf("6264583.33"), NumberUtils.createNumber("6264583.33"),
636-
"createNumber(String) LANG-1187 failed");
623+
assertEquals(Double.valueOf("6264583.33"), NumberUtils.createNumber("6264583.33"), "createNumber(String) LANG-1187 failed");
637624
// LANG-1215
638-
assertEquals(Double.valueOf("193343.82"), NumberUtils.createNumber("193343.82"),
639-
"createNumber(String) LANG-1215 failed");
625+
assertEquals(Double.valueOf("193343.82"), NumberUtils.createNumber("193343.82"), "createNumber(String) LANG-1215 failed");
640626
// LANG-1060
641-
assertEquals(Double.valueOf("001234.5678"), NumberUtils.createNumber("001234.5678"),
642-
"createNumber(String) LANG-1060a failed");
643-
assertEquals(Double.valueOf("+001234.5678"), NumberUtils.createNumber("+001234.5678"),
644-
"createNumber(String) LANG-1060b failed");
645-
assertEquals(Double.valueOf("-001234.5678"), NumberUtils.createNumber("-001234.5678"),
646-
"createNumber(String) LANG-1060c failed");
647-
assertEquals(Double.valueOf("0000.00000"), NumberUtils.createNumber("0000.00000d"),
648-
"createNumber(String) LANG-1060d failed");
649-
assertEquals(Float.valueOf("001234.56"), NumberUtils.createNumber("001234.56"),
650-
"createNumber(String) LANG-1060e failed");
651-
assertEquals(Float.valueOf("+001234.56"), NumberUtils.createNumber("+001234.56"),
652-
"createNumber(String) LANG-1060f failed");
653-
assertEquals(Float.valueOf("-001234.56"), NumberUtils.createNumber("-001234.56"),
654-
"createNumber(String) LANG-1060g failed");
655-
assertEquals(Float.valueOf("0000.10"), NumberUtils.createNumber("0000.10"),
656-
"createNumber(String) LANG-1060h failed");
657-
assertEquals(Float.valueOf("001.1E20"), NumberUtils.createNumber("001.1E20"),
658-
"createNumber(String) LANG-1060i failed");
659-
assertEquals(Float.valueOf("+001.1E20"), NumberUtils.createNumber("+001.1E20"),
660-
"createNumber(String) LANG-1060j failed");
661-
assertEquals(Float.valueOf("-001.1E20"), NumberUtils.createNumber("-001.1E20"),
662-
"createNumber(String) LANG-1060k failed");
663-
assertEquals(Double.valueOf("001.1E200"), NumberUtils.createNumber("001.1E200"),
664-
"createNumber(String) LANG-1060l failed");
665-
assertEquals(Double.valueOf("+001.1E200"), NumberUtils.createNumber("+001.1E200"),
666-
"createNumber(String) LANG-1060m failed");
667-
assertEquals(Double.valueOf("-001.1E200"), NumberUtils.createNumber("-001.1E200"),
668-
"createNumber(String) LANG-1060n failed");
627+
assertEquals(Double.valueOf("001234.5678"), NumberUtils.createNumber("001234.5678"), "createNumber(String) LANG-1060a failed");
628+
assertEquals(Double.valueOf("+001234.5678"), NumberUtils.createNumber("+001234.5678"), "createNumber(String) LANG-1060b failed");
629+
assertEquals(Double.valueOf("-001234.5678"), NumberUtils.createNumber("-001234.5678"), "createNumber(String) LANG-1060c failed");
630+
assertEquals(Double.valueOf("0000.00000"), NumberUtils.createNumber("0000.00000d"), "createNumber(String) LANG-1060d failed");
631+
assertEquals(Float.valueOf("001234.56"), NumberUtils.createNumber("001234.56"), "createNumber(String) LANG-1060e failed");
632+
assertEquals(Float.valueOf("+001234.56"), NumberUtils.createNumber("+001234.56"), "createNumber(String) LANG-1060f failed");
633+
assertEquals(Float.valueOf("-001234.56"), NumberUtils.createNumber("-001234.56"), "createNumber(String) LANG-1060g failed");
634+
assertEquals(Float.valueOf("0000.10"), NumberUtils.createNumber("0000.10"), "createNumber(String) LANG-1060h failed");
635+
assertEquals(Float.valueOf("001.1E20"), NumberUtils.createNumber("001.1E20"), "createNumber(String) LANG-1060i failed");
636+
assertEquals(Float.valueOf("+001.1E20"), NumberUtils.createNumber("+001.1E20"), "createNumber(String) LANG-1060j failed");
637+
assertEquals(Float.valueOf("-001.1E20"), NumberUtils.createNumber("-001.1E20"), "createNumber(String) LANG-1060k failed");
638+
assertEquals(Double.valueOf("001.1E200"), NumberUtils.createNumber("001.1E200"), "createNumber(String) LANG-1060l failed");
639+
assertEquals(Double.valueOf("+001.1E200"), NumberUtils.createNumber("+001.1E200"), "createNumber(String) LANG-1060m failed");
640+
assertEquals(Double.valueOf("-001.1E200"), NumberUtils.createNumber("-001.1E200"), "createNumber(String) LANG-1060n failed");
669641
// LANG-1645
670-
assertEquals(Integer.decode("+0xF"), NumberUtils.createNumber("+0xF"),
671-
"createNumber(String) LANG-1645a failed");
672-
assertEquals(Long.decode("+0xFFFFFFFF"), NumberUtils.createNumber("+0xFFFFFFFF"),
673-
"createNumber(String) LANG-1645b failed");
674-
assertEquals(new BigInteger("+FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("+0xFFFFFFFFFFFFFFFF"),
675-
"createNumber(String) LANG-1645c failed");
642+
assertEquals(Integer.decode("+0xF"), NumberUtils.createNumber("+0xF"), "createNumber(String) LANG-1645a failed");
643+
assertEquals(Long.decode("+0xFFFFFFFF"), NumberUtils.createNumber("+0xFFFFFFFF"), "createNumber(String) LANG-1645b failed");
644+
assertEquals(new BigInteger("+FFFFFFFFFFFFFFFF", 16), NumberUtils.createNumber("+0xFFFFFFFFFFFFFFFF"), "createNumber(String) LANG-1645c failed");
645+
// Map to a BigDecimal, not a Float.
646+
assertEquals(new BigDecimal("0.100000001490116121"), NumberUtils.createNumber("0.100000001490116121"));
676647
}
677648

678649
@Test
@@ -905,6 +876,7 @@ void testIsCreatable() {
905876
compareIsCreatableWithCreateNumber("1.0E-2147483648", false);
906877
compareIsCreatableWithCreateNumber("1E+999999999999999999999", false);
907878
compareIsCreatableWithCreateNumber("1E-999999999999999999999", false);
879+
compareIsCreatableWithCreateNumber("0.100000001490116121", true);
908880
}
909881

910882
@Test

0 commit comments

Comments
 (0)