From a001c19cfd1c655bf5cdbc3066538410ee1cea06 Mon Sep 17 00:00:00 2001
From: Gary Gregory
Date: Fri, 19 Jul 2024 08:26:07 -0400
Subject: [PATCH 1/4] Add testLang1641()
---
.../commons/lang3/time/FastDateFormatTest.java | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
index aa13e28453b..3007c515ef6 100644
--- a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
@@ -47,6 +47,9 @@
* Unit tests {@link org.apache.commons.lang3.time.FastDateFormat}.
*/
public class FastDateFormatTest extends AbstractLangTest {
+
+ private static final String ISO_8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZZ";
+
private static final int NTHREADS = 10;
private static final int NROUNDS = 10000;
@@ -269,6 +272,20 @@ public void testLANG_954() {
FastDateFormat.getInstance(pattern);
}
+ @Test
+ public void testLang1641() {
+ assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT), FastDateFormat.getInstance(ISO_8601_DATE_FORMAT));
+ // commons-lang's GMT TimeZone
+ assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, FastTimeZone.getGmtTimeZone()),
+ FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, FastTimeZone.getGmtTimeZone()));
+ // default TimeZone
+ assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getDefault()),
+ FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getDefault()));
+ // TimeZones that are identical in every way except ID
+ assertNotSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Broken_Hill")),
+ FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Yancowinna")));
+ }
+
@Test
public void testParseSync() throws InterruptedException {
final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS";
From abb0ca487cefc6d6df66600769655b3527a7f63e Mon Sep 17 00:00:00 2001
From: Gary Gregory
Date: Fri, 19 Jul 2024 08:27:03 -0400
Subject: [PATCH 2/4] Rename some test methods
---
.../lang3/time/FastDateFormatTest.java | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
index 3007c515ef6..698dd1ade4c 100644
--- a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
@@ -248,7 +248,7 @@ public void testDateDefaults() {
}
@Test
- public void testLANG_1152() {
+ public void testLang1152() {
final TimeZone utc = FastTimeZone.getGmtTimeZone();
final Date date = new Date(Long.MAX_VALUE);
@@ -259,19 +259,10 @@ public void testLANG_1152() {
assertEquals("17/08/292278994", dateAsString);
}
@Test
- public void testLANG_1267() {
+ public void testLang1267() {
FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
}
- /**
- * According to LANG-954 (https://issues.apache.org/jira/browse/LANG-954) this is broken in Android 2.1.
- */
- @Test
- public void testLANG_954() {
- final String pattern = "yyyy-MM-dd'T'";
- FastDateFormat.getInstance(pattern);
- }
-
@Test
public void testLang1641() {
assertSame(FastDateFormat.getInstance(ISO_8601_DATE_FORMAT), FastDateFormat.getInstance(ISO_8601_DATE_FORMAT));
@@ -286,6 +277,15 @@ public void testLang1641() {
FastDateFormat.getInstance(ISO_8601_DATE_FORMAT, TimeZone.getTimeZone("Australia/Yancowinna")));
}
+ /**
+ * According to LANG-954 (https://issues.apache.org/jira/browse/LANG-954) this is broken in Android 2.1.
+ */
+ @Test
+ public void testLang954() {
+ final String pattern = "yyyy-MM-dd'T'";
+ FastDateFormat.getInstance(pattern);
+ }
+
@Test
public void testParseSync() throws InterruptedException {
final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS";
From 6b7c0be1845ebbe61faa5db2e11159ccb4b9be8a Mon Sep 17 00:00:00 2001
From: Gary Gregory
Date: Sat, 10 Jan 2026 07:52:14 -0500
Subject: [PATCH 3/4] [LANG-1806] NumberUtils.isParsable("1.f") should return
true
- Return true for numbers like 1.2e-5d and 1.2e-5f
- Use a regular expression
---
.../commons/lang3/math/NumberUtils.java | 76 +++++++++----------
.../commons/lang3/math/NumberUtilsTest.java | 64 ++++++++--------
2 files changed, 67 insertions(+), 73 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 2ef56f4d952..2d203ac2e25 100644
--- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
+++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
@@ -21,6 +21,7 @@
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.Objects;
+import java.util.regex.Pattern;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
@@ -104,6 +105,24 @@ public class NumberUtils {
*/
public static final Long LONG_INT_MIN_VALUE = Long.valueOf(Integer.MIN_VALUE);
+ /**
+ * Pattern for ASCII digits only with decimal point, scientific notation, and type suffixes.
+ *
+ *
+ * -? : optional minus sign
+ * (?: : non-capturing group for number formats
+ * [0-9]+ : one or more ASCII digits (integer)
+ * | : OR
+ * [0-9]*\.[0-9]+: optional digits, dot, one or more digits (e.g., .5 or 1.5)
+ * | : OR
+ * [0-9]+\. : one or more digits, dot (e.g., 1.)
+ * )
+ * (?:[eE][+-]?[0-9]+)? : optional exponent (e or E, optional sign, ASCII digits)
+ * [fFdD]? : optional type suffix (f, F, d, D)
+ *
+ */
+ private static final Pattern NUM_PATTERN = Pattern.compile("^-?(?:[0-9]+|[0-9]*\\.[0-9]+|[0-9]+\\.)(?:[eE][+-]?[0-9]+)?[fFdD]?$");
+
/**
* Compares two {@code byte} values numerically. This is the same functionality as provided in Java 7.
*
@@ -730,7 +749,12 @@ public static boolean isNumber(final String str) {
*
*
*
- * Hexadecimal and scientific notations are not considered parsable. See {@link #isCreatable(String)} on those cases.
+ * Hexadecimal notations are not considered parsable. See {@link #isCreatable(String)} for those cases.
+ *
+ *
+ *
+ * Scientific notation (e.g., {@code "1.2e-5"}) and type suffixes (e.g., {@code "2.0f"}, {@code "2.0d"}) are supported
+ * as they are valid for {@link Float#parseFloat(String)} and {@link Double#parseDouble(String)}.
*
*
*
@@ -745,45 +769,19 @@ public static boolean isParsable(final String str) {
if (StringUtils.isEmpty(str)) {
return false;
}
- if (str.charAt(0) == '-') {
- if (str.length() == 1) {
- return false;
- }
- return isParsableDecimal(str, 1);
+ final char lastChar = str.charAt(str.length() - 1);
+ // Use regex for decimal, exponent, or type suffix; otherwise check for integer digits
+ if (str.indexOf('.') >= 0 || str.indexOf('e') >= 0 || str.indexOf('E') >= 0 ||
+ lastChar == 'f' || lastChar == 'F' || lastChar == 'd' || lastChar == 'D') {
+ return NUM_PATTERN.matcher(str).matches();
}
- return isParsableDecimal(str, 0);
- }
-
- /**
- * Tests whether a number string is parsable as a decimal number or integer.
- *
- *
- * - At most one decimal point is allowed.
- * - No signs, exponents or type qualifiers are allowed.
- * - Only ASCII digits are allowed if a decimal point is present.
- *
- *
- * @param str the String to test.
- * @param beginIdx the index to start checking from.
- * @return {@code true} if the string is a parsable number.
- */
- private static boolean isParsableDecimal(final String str, final int beginIdx) {
- // See https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-NonZeroDigit
- int decimalPoints = 0;
- boolean asciiNumeric = true;
- for (int i = beginIdx; i < str.length(); i++) {
- final char ch = str.charAt(i);
- final boolean isDecimalPoint = ch == '.';
- if (isDecimalPoint) {
- decimalPoints++;
- }
- if (decimalPoints > 1 || !isDecimalPoint && !Character.isDigit(ch)) {
- return false;
- }
- if (!isDecimalPoint) {
- asciiNumeric &= CharUtils.isAsciiNumeric(ch);
- }
- if (decimalPoints > 0 && !asciiNumeric) {
+ // Simple integer: optional minus followed by Unicode digits (for Integer.parseInt compatibility)
+ final int start = str.charAt(0) == '-' ? 1 : 0;
+ if (start == str.length()) {
+ return false; // just "-"
+ }
+ for (int i = start; i < str.length(); i++) {
+ if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
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 528039c9cf6..c96986be7c7 100644
--- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
@@ -37,6 +37,8 @@
import org.apache.commons.lang3.AbstractLangTest;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
/**
* Tests {@link org.apache.commons.lang3.math.NumberUtils}.
@@ -1004,36 +1006,14 @@ void testIsNumberLANG992() {
compareIsNumberWithCreateNumber("0.4790", true);
}
- @Test
- void testIsParsable() {
- assertFalse(NumberUtils.isParsable(null));
- assertFalse(NumberUtils.isParsable(""));
- assertFalse(NumberUtils.isParsable("0xC1AB"));
- assertFalse(NumberUtils.isParsable("65CBA2"));
- assertFalse(NumberUtils.isParsable("pendro"));
- assertFalse(NumberUtils.isParsable("64, 2"));
- assertFalse(NumberUtils.isParsable("64.2.2"));
- assertFalse(NumberUtils.isParsable("64.."));
- assertTrue(NumberUtils.isParsable("64."));
- assertTrue(NumberUtils.isParsable("-64."));
- assertFalse(NumberUtils.isParsable("64L"));
- assertFalse(NumberUtils.isParsable("-"));
- assertFalse(NumberUtils.isParsable("--2"));
- assertTrue(NumberUtils.isParsable("64.2"));
- assertTrue(NumberUtils.isParsable("64"));
- assertTrue(NumberUtils.isParsable("018"));
- assertTrue(NumberUtils.isParsable(".18"));
- assertTrue(NumberUtils.isParsable("-65"));
- assertTrue(NumberUtils.isParsable("-018"));
- assertTrue(NumberUtils.isParsable("-018.2"));
- assertTrue(NumberUtils.isParsable("-.236"));
- assertTrue(NumberUtils.isParsable("2."));
- // TODO assertTrue(NumberUtils.isParsable("2.f"));
- // TODO assertTrue(NumberUtils.isParsable("2.d"));
- // Float.parseFloat("1.2e-5f")
- // TODO assertTrue(NumberUtils.isParsable("1.2e-5f"));
- // Double.parseDouble("1.2e-5d")
- // TODO assertTrue(NumberUtils.isParsable("1.2e-5d"));
+ @ParameterizedTest
+ @ValueSource(strings = { "", "0xC1AB", "65CBA2", "pendro", "64, 2", "64.2.2", "64..", "64L", "-", "--2",
+ // Invalid scientific notation.
+ "e5", "1e", "1e+", "1e-", "1ee5", "1e5e5",
+ // Invalid type suffixes.
+ "f", "d", "-f", "-d", })
+ void testIsParsableFalse(final String input) {
+ assertFalse(NumberUtils.isParsable(input));
}
/**
@@ -1056,6 +1036,22 @@ void testIsParsableFullWidthUnicodeJDK8326627() {
assertFalse(NumberUtils.isParsable("0." + fullWidth123));
}
+ @Test
+ void testIsParsableNull() {
+ // Can't use null in @ValueSource(strings)
+ assertFalse(NumberUtils.isParsable(null));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = { "64.", "-64.", "64.2", "64", "018", ".18", "-65", "-018", "-018.2", "-.236", "2.", "2.f", "2.d", "1.2e-5f", "1.2e-5d",
+ // Additional tests for scientific notation.
+ "1e5", "1E5", "1.2e5", "1.2E5", "1.2e+5", "1.2e-5", "-1.2e-5", "1e5f", "1e5F", "1e5d", "1e5D",
+ // Additional tests for type suffixes.
+ "2f", "2F", "2d", "2D", "2.0f", "2.0F", "2.0d", "2.0D", "-2.0f", "-2.0d", })
+ void testIsParsableTrue(final String input) {
+ assertTrue(NumberUtils.isParsable(input));
+ }
+
@Test
void testLang1087() {
// no sign cases
@@ -1087,8 +1083,8 @@ void testLang1729IsParsableByte() {
void testLang1729IsParsableDouble() {
assertTrue(isParsableDouble("1"));
assertTrue(isParsableDouble("1."));
- // TODO assertTrue(isParsableDouble("1.f"));
- // TODO assertTrue(isParsableDouble("1.d"));
+ assertTrue(isParsableDouble("1.f"));
+ assertTrue(isParsableDouble("1.d"));
assertTrue(isParsableDouble("1.0"));
assertFalse(isParsableDouble("1.0."));
assertFalse(isParsableDouble("1 2 3"));
@@ -1099,8 +1095,8 @@ void testLang1729IsParsableDouble() {
void testLang1729IsParsableFloat() {
assertTrue(isParsableFloat("1"));
assertTrue(isParsableFloat("1."));
- // TODO assertTrue(isParsableFloat("1.f"));
- // TODO assertTrue(isParsableFloat("1.d"));
+ assertTrue(isParsableFloat("1.f"));
+ assertTrue(isParsableFloat("1.d"));
assertTrue(isParsableFloat("1.0"));
assertFalse(isParsableFloat("1.0."));
assertFalse(isParsableFloat("1 2 3"));
From 06a6b1f085a05fd1ec68fc9c94c9d5d236f75ac4 Mon Sep 17 00:00:00 2001
From: Gary Gregory
Date: Sun, 11 Jan 2026 11:00:30 -0500
Subject: [PATCH 4/4] [LANG-1806] NumberUtils.isParsable("1.f") should return
true
- Return true for numbers like 1.2e-5d and 1.2e-5f
- Return true when one of the following would work:
-- Double.parseDouble(String)
-- Float.parseFloat(String)
-- Long.parseLong(String)
-- Integer.parseInteger(String)
There are so many cases that it's simpler to try to parse and catch
exceptions, instead of re-creating all the parsing rules from the JRE.
The only downside is that number instances are created and discarded.
---
.../commons/lang3/math/NumberUtils.java | 60 ++++---------
.../commons/lang3/math/NumberUtilsTest.java | 90 ++++++++++++++++++-
2 files changed, 104 insertions(+), 46 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 2d203ac2e25..6abd66502a5 100644
--- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
+++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
@@ -21,7 +21,7 @@
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.Objects;
-import java.util.regex.Pattern;
+import java.util.function.Consumer;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
@@ -105,23 +105,14 @@ public class NumberUtils {
*/
public static final Long LONG_INT_MIN_VALUE = Long.valueOf(Integer.MIN_VALUE);
- /**
- * Pattern for ASCII digits only with decimal point, scientific notation, and type suffixes.
- *
- *
- * -? : optional minus sign
- * (?: : non-capturing group for number formats
- * [0-9]+ : one or more ASCII digits (integer)
- * | : OR
- * [0-9]*\.[0-9]+: optional digits, dot, one or more digits (e.g., .5 or 1.5)
- * | : OR
- * [0-9]+\. : one or more digits, dot (e.g., 1.)
- * )
- * (?:[eE][+-]?[0-9]+)? : optional exponent (e or E, optional sign, ASCII digits)
- * [fFdD]? : optional type suffix (f, F, d, D)
- *
- */
- private static final Pattern NUM_PATTERN = Pattern.compile("^-?(?:[0-9]+|[0-9]*\\.[0-9]+|[0-9]+\\.)(?:[eE][+-]?[0-9]+)?[fFdD]?$");
+ private static boolean accept(final Consumer consumer, final T obj) {
+ try {
+ consumer.accept(obj);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
/**
* Compares two {@code byte} values numerically. This is the same functionality as provided in Java 7.
@@ -186,7 +177,7 @@ public static int compare(final short x, final short y) {
* Returns {@code null} if the string is {@code null}.
*
*
- * @param str a {@link String} to convert, may be null.
+ * @param str a {@link String} to convert, may be null.Return
* @return converted {@link BigDecimal} (or null if the input is null).
* @throws NumberFormatException if the value cannot be converted.
*/
@@ -749,11 +740,7 @@ public static boolean isNumber(final String str) {
*
*
*
- * Hexadecimal notations are not considered parsable. See {@link #isCreatable(String)} for those cases.
- *
- *
- *
- * Scientific notation (e.g., {@code "1.2e-5"}) and type suffixes (e.g., {@code "2.0f"}, {@code "2.0d"}) are supported
+ * Scientific notation (for example, {@code "1.2e-5"}) and type suffixes (e.g., {@code "2.0f"}, {@code "2.0d"}) are supported
* as they are valid for {@link Float#parseFloat(String)} and {@link Double#parseDouble(String)}.
*
*
@@ -763,29 +750,14 @@ public static boolean isNumber(final String str) {
*
* @param str the String to check.
* @return {@code true} if the string is a parsable number.
+ * @see Integer#parseInt(String)
+ * @see Long#parseLong(String)
+ * @see Double#parseDouble(String)
+ * @see Float#parseFloat(String)
* @since 3.4
*/
public static boolean isParsable(final String str) {
- if (StringUtils.isEmpty(str)) {
- return false;
- }
- final char lastChar = str.charAt(str.length() - 1);
- // Use regex for decimal, exponent, or type suffix; otherwise check for integer digits
- if (str.indexOf('.') >= 0 || str.indexOf('e') >= 0 || str.indexOf('E') >= 0 ||
- lastChar == 'f' || lastChar == 'F' || lastChar == 'd' || lastChar == 'D') {
- return NUM_PATTERN.matcher(str).matches();
- }
- // Simple integer: optional minus followed by Unicode digits (for Integer.parseInt compatibility)
- final int start = str.charAt(0) == '-' ? 1 : 0;
- if (start == str.length()) {
- return false; // just "-"
- }
- for (int i = start; i < str.length(); i++) {
- if (!Character.isDigit(str.charAt(i))) {
- return false;
- }
- }
- return true;
+ return accept(Double::parseDouble, str) || accept(Long::parseLong, str) || accept(Float::parseFloat, str) || accept(Long::parseLong, str);
}
private static boolean isSign(final char ch) {
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 c96986be7c7..105dda46204 100644
--- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
@@ -1006,6 +1006,46 @@ void testIsNumberLANG992() {
compareIsNumberWithCreateNumber("0.4790", true);
}
+ @ParameterizedTest
+ // @formatter:off
+ @ValueSource(strings = {
+ // Decimal floating-point literals (no suffix or 'd'/'D' suffix)
+ "3.14",
+ "3.14d",
+ "3.14D",
+ ".5",
+ ".5d",
+ "5.",
+ "5.d",
+ "5d",
+ "0.0",
+ "0.0d",
+ // Exponential (scientific) notation
+ "1.23e10",
+ "1.23e10d",
+ "1.23E10",
+ "1.23e-10",
+ "1.23e-10d",
+ "1e5",
+ "1e5d",
+ ".5e3",
+ ".5e3d",
+ // Hexadecimal floating-point literals
+ "0x1.8p3",
+ "0x1.8p3d",
+ "0x.8p0",
+ "0x1p-3",
+ "0x1.fffffffffffffp1023",
+ "0x1.fffffffffffffp1023d",
+ // With leading zeros
+ "01.5",
+ "01.5d" })
+ // @formatter:on
+ void testIsParsableDoubleTrue(final String input) {
+ Double.parseDouble(input);
+ assertTrue(NumberUtils.isParsable(input));
+ }
+
@ParameterizedTest
@ValueSource(strings = { "", "0xC1AB", "65CBA2", "pendro", "64, 2", "64.2.2", "64..", "64L", "-", "--2",
// Invalid scientific notation.
@@ -1016,6 +1056,35 @@ void testIsParsableFalse(final String input) {
assertFalse(NumberUtils.isParsable(input));
}
+ @ParameterizedTest
+ // @formatter:off
+ @ValueSource(strings = {
+ // Decimal floating-point literals
+ "3.14f",
+ "3.14F",
+ ".5f",
+ "5.f",
+ "5f",
+ "0.0f",
+ // Exponential (scientific) notation
+ "1.23e10f",
+ "1.23E10f",
+ "1.23e-10f",
+ "1e5f",
+ ".5e3f",
+ // Hexadecimal floating-point literals
+ "0x1.8p3f",
+ "0x.8p0f",
+ "0x1p-3f",
+ "0x1.fffffep127f",
+ // With leading zeros
+ "01.5f"})
+ // @formatter:on
+ void testIsParsableFloatTrue(final String input) {
+ Float.parseFloat(input);
+ assertTrue(NumberUtils.isParsable(input));
+ }
+
/**
* Tests https://issues.apache.org/jira/browse/LANG-1729
*
@@ -1043,11 +1112,28 @@ void testIsParsableNull() {
}
@ParameterizedTest
- @ValueSource(strings = { "64.", "-64.", "64.2", "64", "018", ".18", "-65", "-018", "-018.2", "-.236", "2.", "2.f", "2.d", "1.2e-5f", "1.2e-5d",
+ // @formatter:off
+ @ValueSource(strings = {
+ "64.",
+ "-64.",
+ "64.2",
+ "64",
+ "018",
+ ".18",
+ "-65",
+ "-018",
+ "-018.2",
+ "-.236",
+ "2.",
+ "2.f",
+ "2.d",
+ "1.2e-5f",
+ "1.2e-5d",
// Additional tests for scientific notation.
"1e5", "1E5", "1.2e5", "1.2E5", "1.2e+5", "1.2e-5", "-1.2e-5", "1e5f", "1e5F", "1e5d", "1e5D",
// Additional tests for type suffixes.
- "2f", "2F", "2d", "2D", "2.0f", "2.0F", "2.0d", "2.0D", "-2.0f", "-2.0d", })
+ "2f", "2F", "2d", "2D", "2.0f", "2.0F", "2.0d", "2.0D", "-2.0f", "-2.0d" })
+ // @formatter:on
void testIsParsableTrue(final String input) {
assertTrue(NumberUtils.isParsable(input));
}