Dear julia experts—I would like to print very small numbers in terms of eps(Float64). Something like
julia> Base.show(io::IO, p::Float64) =
print(io, (abs(p)<1000*eps(Float64)) ? sprintf("%.3feps", (p/eps(Float64))) : p)
This runs into a “minor” difficulty, of course. I have overridden the original Base.show. I need to rescue it first.
An even more minor issue is that I would like to have it work later under 0.7 and 1.0, too. will it still work the same?
Just define your own printsmall(x)
function; you generally shouldn’t overwrite Base
methods on Base types.
Note that print
by default calls show
, so writing show(x)
in terms of print(x)
as you have done here will probably lead to a dispatch loop.
hi steven: yes, I know that the final term does cause the fatal loop. this is what I need to avoid.
but I also want to do this, because there is an advantage for overriding Base.show()
. Even if Float64 then appear in vectors or structs, they still display how I want them to display.
Realize that by changing Float64
display your code may not be composable with other code that relies on the Base behavior, which is a big drawback.
One way to change the display of Base types without composability problems (i.e., without type piracy) would be to define your own struct MyIO <: IO; io::IO; end
type wrapping another io
stream, and then define your own Base.show(io::MyIO, x)
methods, falling back to Base.show(io::MyIO, x) = show(io.io, x)
. You can even redirect stdout
to go to a MyIO
stream.
That being said, if you really want to do this you need to look at what Base.show(io, x::Float64)
normally calls. Currently, it is a method on Union{Float32,Float64}
, so by defining your own show(io, ::Float64)
you are just providing a more specific method, not overwriting the existing method. Therefore, you can call the old method by using invoke
.
4 Likes
in case someone else ever needs this, the file is .../julia/base/grisu/grisu.jl
function Base.show(io::IO, x::Union{Float64,Float32})
if get(io, :compact, false)
_show(io, x, PRECISION, 6, true, true)
else
_show(io, x, SHORTEST, 0, true, false)
end
end