test: fix comparison of integers wider than i128 - #13719
Conversation
integers() parsed both operands with i128, so an operand needing more digits than that range holds was rejected as an invalid integer with exit code 2. GNU compares integers of arbitrary width and returns 0 or 1 instead of erroring. Parse each operand into a sign and its decimal digits and compare those directly: sign first, then digit count, then bytewise over the remaining digits. This lifts the width limit from all six integer operators (-eq, -ne, -lt, -le, -gt, -ge) without adding a dependency, and leaves the set of accepted operands unchanged. Fixes uutils#12874 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Ready to approve
The new comparison logic is self-contained, preserves the documented acceptance/rejection behavior, and is supported by comprehensive new unit and integration tests.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR fixes GNU compatibility in the test utility by removing the effective i128 width limit for integer comparisons, allowing arbitrarily large (decimal) integer operands while preserving the existing “reject set” and error behavior.
Changes:
- Replace
i128parsing in integer comparisons with a sign+digits representation and lexicographic magnitude comparison (no width limit). - Re-enable and expand integration tests covering operands beyond
i128, large negatives, mixed signs, and normalization (-0,+0, leading zeros). - Add unit tests validating correct ordering and continued rejection of malformed/non-decimal inputs.
File summaries
| File | Description |
|---|---|
| tests/by-util/test_test.rs | Re-enables stale ignored test and adds integration coverage for very large integer comparisons and malformed operand handling. |
| src/uu/test/src/test.rs | Implements width-unlimited integer comparison by parsing operands into sign+digits and comparing by sign/length/lexicographic order; adds unit tests. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
Merging this PR will improve performance by 22.61%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Simulation | df_with_path |
699.9 µs | 570.8 µs | +22.61% |
Tip
Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.
Comparing dhruv-15-03:test-bigint-compare (a31150b) with main (b13ee7a)
Footnotes
-
46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
|
GNU testsuite comparison: |
|
PR message is much too verbose, please write it by hand instead of proxying the burden of understanding both your patch and AI slop to maintainers. |
|
Fair point - I've cut it down to the problem, the cause and the fix. |
|
Thank you ! |
Fixes #12874
testrejects integers that don't fit ini128:GNU has no width limit here. All six integer operators are affected.
integers()parsed both operands asi128, so anything wider failedparse().They're now parsed into a sign plus decimal digits (leading zeros stripped,
-0normalized) and compared on sign, then digit count, then bytewise. No width limit
and no new dependency.
The set of accepted operands is unchanged -
0x10,1e3,123.45,1_0,5-,-,+, empty and non-UTF-8 all still fail the same way with exit 2. The digitsare validated here rather than handed to a bignum type because that reject set has
to be preserved either way, and once the validator exists the comparison is short.
test_values_greater_than_i64_allowedwas#[ignore]d, but its input fits ini128and passes on main today, so the ignore was stale. Re-enabled, with a newtest for
i128::MAX + 1andi128::MIN - 1.Checked with
cargo test -p uu_testand thetest_testintegration suite, anddiffed against GNU
testover 50 cases covering all six operators, largenegatives, sign and leading-zero handling, and the invalid inputs above. Output
matched. The GNU build I had available was 8.32, not 9.x.