Skip to content

Ensure consistency between NumberUtils.isCreatable and createNumber for extreme exponents#1623

Open
FloydDsilva wants to merge 10 commits intoapache:masterfrom
FloydDsilva:fix/num-isCreatable
Open

Ensure consistency between NumberUtils.isCreatable and createNumber for extreme exponents#1623
FloydDsilva wants to merge 10 commits intoapache:masterfrom
FloydDsilva:fix/num-isCreatable

Conversation

@FloydDsilva
Copy link
Copy Markdown

Background
NumberUtils.isCreatable(String) previously returned true for certain scientific‑notation inputs (e.g. 1E-2147483648) that cannot be represented by any Java Number type. Calling NumberUtils.createNumber with such inputs resulted in a NumberFormatException, breaking the implied contract between the two methods.

Changes

Updated isCreatable to reject unrepresentable negative exponents in scientific notation.
Refined exponent parsing to correctly handle type suffixes (D, F, L) and preserve valid inputs.
Updated createNumber to gracefully handle NumberFormatException raised during BigDecimal creation by propagating a consistent and descriptive failure for invalid values.

Result
These changes restore consistency between isCreatable and createNumber, ensuring that isCreatable only returns true for values that createNumber can successfully construct, while keeping existing behavior intact for all valid numeric representations across supported Java versions.

Test cases for the same has been added.

floyd.dsilva added 3 commits April 3, 2026 17:43
…rror handling for invalid exponential formats in createNumber and updated isCreatable to handle edge cases. Added new test cases for extreme exponent values.
@garydgregory
Copy link
Copy Markdown
Member

Hello @FloydDsilva

-1: The build fails. Please run 'mvn' by itself before you push.

try {
return createBigDecimal(str);
} catch (final NumberFormatException ignored) {
throw new NumberFormatException(str + " is not a valid number.");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem necessary. Also the original cause is lost, making the input harder to debug.

Copy link
Copy Markdown
Member

@garydgregory garydgregory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@FloydDsilva

Please see my comment.

floyd.dsilva added 2 commits April 5, 2026 18:27
… removing unnecessary line breaks and ensuring consistent formatting.
@FloydDsilva
Copy link
Copy Markdown
Author

sorry for the failed build it did not give me any issue when i ran "mvn"

@FloydDsilva
Copy link
Copy Markdown
Author

i think the behaviour for BigDecimal for java 8 and java 21 is different for 1E2147483648

@garydgregory
Copy link
Copy Markdown
Member

i think the behaviour for BigDecimal for java 8 and java 21 is different for 1E2147483648

Then you'll need to account for that...

…rge exponent values based on Java version. Updated corresponding test cases for consistency.
Copy link
Copy Markdown
Member

@garydgregory garydgregory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @FloydDsilva

Thank you for your updates. Please see my comment.
TY!

}
} catch (final NumberFormatException ignored) {
return false;
return ("2147483648".equals(expStr) || "+2147483648".equals(expStr)) && SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_21);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is rather messy IMO. You'll need to provide comments here to explain what's going on. The magic strings should likely be derived from constants like Integer.MAX_VALUE.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey i have refactored the code and also added more test cases. Kindly let me know about if more changes are required.

compareIsCreatableWithCreateNumber(".e10", false); // LANG-1646
compareIsCreatableWithCreateNumber(".e10D", false); // LANG-1646
compareIsCreatableWithCreateNumber("1E-2147483648", false);
compareIsCreatableWithCreateNumber("1E2147483648", SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_21));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need more tests around the edge cases.
TY!

floyd.dsilva and others added 3 commits April 8, 2026 22:06
…xponent values for Java 21 and later. Added comprehensive test cases to validate behavior for various exponent scenarios.
@garydgregory
Copy link
Copy Markdown
Member

garydgregory commented Apr 8, 2026

@FloydDsilva

I had to fix more Checkstyle errors... Do run mvn as noted in the PR template before you push and fix all issues please.

Copy link
Copy Markdown
Member

@garydgregory garydgregory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@FloydDsilva

The unit tests fail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants