I’m not sure if this is the intended behavior:
julia> 0.5
0.5
julia> big(0.5)
0.50
julia> big(0.5) == 0.5
true
Why the extra 0
at the end for a BigFloat
?
I’m not sure if this is the intended behavior:
julia> 0.5
0.5
julia> big(0.5)
0.50
julia> big(0.5) == 0.5
true
Why the extra 0
at the end for a BigFloat
?
Output is done by the show function which is different for the two types:
julia> @which show(stdout,big(0.5))
show(io::IO, b::BigFloat) in Base.MPFR at mpfr.jl:1002
julia> @which show(stdout,0.5)
show(io::IO, x::T) where T<:Union{Float16, Float32, Float64} in Base.Ryu at ryu\Ryu.jl:111
This is show for BigFloat:
function show(io::IO, b::BigFloat)
if get(io, :compact, false)
print(io, _string(b, 5))
else
print(io, _string(b))
end
end
And this for standard Float64:
function Base.show(io::IO, x::T, forceuntyped::Bool=false, fromprint::Bool=false) where {T <: Base.IEEEFloat}
compact = get(io, :compact, false)::Bool
buf = Base.StringVector(neededdigits(T))
typed = !forceuntyped && !compact && get(io, :typeinfo, Any) != typeof(x)
pos = writeshortest(buf, 1, x, false, false, true, -1,
(x isa Float32 && !fromprint) ? UInt8('f') : UInt8('e'), false, UInt8('.'), typed, compact)
write(io, resize!(buf, pos - 1))
return
end
I didn’t checked now for the specific additional 0
in the bigFloat case, but you can play around with both implementations to explore the differences.
For the bigFloat you also need (from the same file):
function _string(x::BigFloat, fmt::String)::String
isfinite(x) || return string(Float64(x))
_prettify_bigfloat(string_mpfr(x, fmt))
end
_string(x::BigFloat) = _string(x, "%.Re")
_string(x::BigFloat, k::Integer) = _string(x, "%.$(k)Re")
string(b::BigFloat) = _string(b)
print(io::IO, b::BigFloat) = print(io, string(b))
but you can open those files on your own to get all needed dependencies, like
_prettify_bigfloat(s::String)::String
I realize that the methods are different, but my question was if this behavior is intended or if it is a bug in the display format.
I don’t know, probably not intended that there is some special reasoning behind it. But that doesn’t make it a bug. I would say: it’s not important enough to deal with it in a priorized way.
The string is rendered by MPFR as “5.0e-1”. Julia gets rid of the “e” notation by moving the decimal point.
For convenience/reference, the code that does that is here:
function _prettify_bigfloat(s::String)::String
mantissa, exponent = split(s, 'e')
if !occursin('.', mantissa)
mantissa = string(mantissa, '.')
end
mantissa = rstrip(mantissa, '0')
if endswith(mantissa, '.')
mantissa = string(mantissa, '0')
end
expo = parse(Int, exponent)
if -5 < expo < 6
expo == 0 && return mantissa
int, frac = split(mantissa, '.')
if expo > 0
expo < length(frac) ?
string(int, frac[1:expo], '.', frac[expo+1:end]) :
string(int, frac, '0'^(expo-length(frac)), '.', '0')
else
neg = startswith(int, '-')
neg == true && (int = lstrip(int, '-'))
@assert length(int) == 1
string(neg ? '-' : "", '0', '.', '0'^(-expo-1), int, frac)
end
else
string(mantissa, 'e', exponent)
end
end
From a brief study of this code, it seems like the line
string(neg ? '-' : "", '0', '.', '0'^(-expo-1), int, frac)
…could be tweaked to not include frac
if it is zero, as is the case with 0.5.
Maybe that behavior is there for a reason, but I guess I could submit a PR and see what feedback I get.
Update: I’ve submitted a PR: mpfr.jl: don't add extra zero when pretty-printing BigFloats by waldyrious · Pull Request #40513 · JuliaLang/julia · GitHub