The title says it all, but generally I want to avoid a negative number that is rounded to all-zeros by printf to have a -.
julia> using Printf
julia> @sprintf("%.1f", -0.001)
"-0.0"
see a truly horrid solution here
function my_format(x::Real)
s = @sprintf("%.1f", x)
m = match(r"^-([0.]+)$", s)
if m ≡ nothing
s
else
m.captures[1]
end
end
AFAIK printf doesn’t support this. Something like x = round(x; digits = 1) == 0 ? 0 : x seems slightly cleaner than tweaking the output, especially when your format string specifies padding etc.
This is standard IEEE 754 floating-point behavior, and there are three workarounds,
Along the lines as suggested by @pfitzseb
using Printf
val = -0.001
# If the value rounds to 0.0, use the absolute value
formatted = @sprintf("%.1f", abs(val) < 0.05 ? 0.0 : val)
or a slightly less horrid function
using Printf
val = -0.001
# Add 0.0 to strip the negative sign from -0.0
# round(val, digits=1) results in -0.0, but -0.0 + 0.0 == 0.0
clean_val = round(val, digits=1) + 0.0
@sprintf("%.1f", clean_val) # Output: "0.0"
I’d avoid the only other alternative I see
replace(@sprintf("%.1f", -0.001), "-0.0" => "0.0")
That may well be, but it does not make sense in my context (generating tables for a research paper). In that context, the -0.0 is an unnecessary distraction.
I wish there was a package that would simply decompose a (binary) float to a bunch of digits (dumped into a Vector{UInt8} or similar), a decimal exponent, and a sign, then let the user deal with that for further processing. Of course the internals of Ryu in Base do exactly that, but it is not part of the API and has a different API.