Skip to content

Preserve fractional bound in BigIntegerValidator range checks#407

Merged
garydgregory merged 2 commits into
apache:masterfrom
sahvx655-wq:bigint-fractional-bound
Jun 22, 2026
Merged

Preserve fractional bound in BigIntegerValidator range checks#407
garydgregory merged 2 commits into
apache:masterfrom
sahvx655-wq:bigint-fractional-bound

Conversation

@sahvx655-wq

Copy link
Copy Markdown
Contributor

The Number-typed minValue and maxValue overrides convert both operands with toBigInteger before comparing, and toBigInteger truncates a non-integer bound towards zero. A fractional bound therefore loses its fractional part before the test, so the verdict is wrong: minValue(BigInteger 5, 5.9) returns true although 5 is below 5.9 (the bound is floored to 5), and maxValue(BigInteger -5, -5.9) returns true although -5 is above -5.9. I noticed this while checking these overloads against BigDecimalValidator, which already compares the same mixed Number bounds exactly, so the two validators disagree on identical inputs.

The fix compares both operands as BigDecimal so a non-integer bound keeps its value. Whole-number bounds and BigIntegers outside the long range are unaffected, and keeping the comparison inside the override mirrors BigDecimalValidator rather than pushing rounding onto callers. Left unfixed, any range check given a Double, Float or BigDecimal bound with a fractional part can admit values just outside the requested range.

@garydgregory garydgregory left a comment

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.

@sahvx655-wq
Thank you for the PR.
Please see my comment.

if (value instanceof BigInteger) {
return new BigDecimal((BigInteger) value);
}
if (value instanceof Long) {

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.

Hello @sahvx655-wq
You missed the java.math.BigDecimal.valueOf(double) shortcut here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. I've added a Double branch using BigDecimal.valueOf(((Double) value).doubleValue()) so it matches the toBigInteger helper just below, which already takes that path with the same "no need to roundtrip with a string" note. The fall-through stays on new BigDecimal(value.toString()) for the remaining types (Float keeps its own canonical short form that way rather than picking up the widened double representation).

Pushed in 3b48460 and the range tests still pass.

@garydgregory garydgregory merged commit 0996a3e into apache:master Jun 22, 2026
10 checks passed
@garydgregory garydgregory changed the title preserve fractional bound in BigIntegerValidator range checks Preserve fractional bound in BigIntegerValidator range checks Jun 22, 2026
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