Skip to content

Conversation

@nickorlow
Copy link

@nickorlow nickorlow commented Mar 20, 2025

Changes made for this PR are based on PR #7458 due to its extensive changes in the formatting code.

Fixes Issue #7509

Old behavior:

$ ./target/debug/coreutils printf "%.0d\n" 0
0

New behavior:

$ ./target/debug/coreutils printf "%.0d\n" 0

drinkcat and others added 14 commits March 19, 2025 11:46
Will make it possible to directly print ExtendedBigDecimal in `seq`,
and gradually get rid of limited f64 precision in other tools
(e.g. `printf`).

Changes are mostly mechanical, we reexport ExtendedBigDecimal directly
in format to keep the imports slightly shorter.
Using an associated type in Formatter trait was quite nice, but, in
a follow-up change, we'd like to pass a _reference_ to the Float
Formatter, while just passing i64/u64 as a value to the Int
formatters. Associated type doesn't allow for that, so we turn
it into a generic instead.

This makes Format<> a bit more complicated though, as we need
to specify both the Formatter, _and_ the type to be formatted.
Some test cases require to handle "negative" NaN. Handle it
similarly to "positive" NaN.
Only changes the external interface, right now the number is
casted back to f64 for printing. We'll update that in follow-up.
First modify Format.fmt to extract absolute value and sign, then
modify printing on non-finite values (inf or nan).
Also add a few unit tests to make sure precision is not lost anymore.
No more f64 operations needed, we just trim (or extend) BigDecimal to
appropriate precision, get the digits as a string, then add the
decimal point.

Similar to what BigDecimal::write_scientific_notation does, but
we need a little bit more control.
Similar logic to scientific printing. Also add a few more tests
around corner cases where we switch from decimal to scientific
printing.
Display hexadecimal floats with arbitrary precision.

Note that some of the logic will produce extremely large
BitInt as intermediate values: there is some optimization
possible here, but the current implementation appears to work
fine for reasonable numbers (e.g. whatever would previously
fit in a f64, and even with somewhat large precision).
`printf "%05.2f" inf` should print `  inf`, not `00inf`.

Add a test to cover that case, too.
Now that uucore format functions take in an ExtendedBigDecimal,
we can use those in all cases.
In most common use cases:
 - We can bypass a lot of `write_output` when width == 0.
 - Simplify format_float_decimal when the input is an integer.

Also document another interesting case in src/uu/seq/BENCHMARKING.md.
- Formatter<u64> and Formatter<i64> now return early if precision and value are 0
@nickorlow
Copy link
Author

nickorlow commented Mar 20, 2025

Should've read contrib.md first

@nickorlow nickorlow closed this Mar 20, 2025
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