Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

\%d() inconsistency with Float64 #5

Closed
ryofurue opened this issue Jan 9, 2024 · 4 comments
Closed

\%d() inconsistency with Float64 #5

ryofurue opened this issue Jan 9, 2024 · 4 comments

Comments

@ryofurue
Copy link

ryofurue commented Jan 9, 2024

When you use a Float64 number with the \%4.4d(x) format, there are no leading zeros. A sample code is below.

I know that using a Float64 for the d format descriptor is the cause of the problem, but it would be nice if the \%4.4d(x) behaved as if it were %d4.4d(Int(x)).

using StrFormat

func(x) = println(f"\%4.4d(x)")

vals  = [1.0, 22.5, 4321.0, 56789.0]
ivals = [1, 22, 4321, 56789]

map(func, vals) # lacks the leading zeros
map(func, ivals) # fine, as expected.

Unlike most other programming languages, Julia silently converts Float's with Int's if the conversion is exact and complains if it's not:

ia = Array{Int}(undef, 2)
ia .= [1.0, 22.0] # -> fine
@show ia
ia .= [1.0, 22.5] # -> error because Int(22.5) isn't exact.
@show ia

I hope that the d format descriptor honors this "spirit" of Julia.

@ScottPJones
Copy link
Member

ScottPJones commented Feb 19, 2024

This should actually be raised as an issue with Format.jl.

StrFormat is just a very lightweight wrapper replacing \%<format specifiers><format code>(val) with cfmt("%<formatspecifiers><format code>", val), \%(val, args...) with fmt(val, args...), and \{<format string>}(val) with pyfmt("<format string>", val).

I will look into this, thanks for the input!

@ScottPJones
Copy link
Member

ScottPJones commented Feb 19, 2024

I've compared things a bit - for C/C++ formatted strings, you get garbage results if you use a double (Float64) with the d specifier. For Python, you get an error message using d (no matter whether or not the value can be exactly converted to an integer).
Normally, to achieve the results I think you want, you'd use "%04.0f" (which will work for integers or floats [it rounds the floats])

I don't think I should change how Format handles the d specifier, it is consistent with Julia's Printf function, and you can use the f specifier to get integer results, for both floating point and integer input.

@ryofurue
Copy link
Author

I tried to understand your points, but I don't see how consistency with other languages matter. The goal should be usefulness to the end user (Julia programmer).

Do you really think that giving a garbage result is a good outcome for the user? I don't think you do.

Because Julia silently converts 1.0 to 1 usually, getting a sensible result from the format "%4.4d(x)" even when x is Float64 is a good outcome. Is there a downside here?

Then, if we give a sensible outcome, which is better, " 1" or "0001" ?

Do you really think that giving "0001" for 1 and " 1" for 1.0 is the best result for the user? Would there any downside in giving "0001" for both cases?

If you argued that an error should be the right outcome, then there is some merit in that argument. But, there is no valid argument for " 1" from "%4.4d(x)" with x being Float64. The outcome should be error or "0001".

@ScottPJones
Copy link
Member

A big part of the problem, is that cfmt basically uses (a copy of) the Printf code for this operation.
It's not a issue of consistency with other languages that is mostly the issue, it's consistency with Julia's stdlib Printf library.
If you can get Printf.jl changed, I'll happily change Format.jl to match.

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

No branches or pull requests

2 participants