Inconsistent rounding for parameters in savename
Opened this issue · 3 comments
When using savename
, some unexpected behaviour can happen when using some parameter values with the sigdigits
keyword. This seems to be due to the fact that savename
uses the round
function to format numbers, which is designed for outputting numbers as strings. One issue occurs when using very small or large numbers, and is due to a known bug in round
, but is machine specific.
For example,
julia> savename("test", (p1=3.6e-23,), sigdigits=1)
"test_p1=4.0000000000000004e-23"
but for one order of magnitude larger
julia> savename("test", (p1=3.6e-22,), sigdigits=1)
"test_p1=4e-22"
Additionally, while it may round the correct number of significant digits, the output will not necessarily represent the specified number of significant digits. Specifically, this occurs when there should be additional zeros, which are either not be added to the given number, or are dropped when the number rounds to something that can be represented with fewer digits. For example,
julia> savename("test", (p1=3.5e-6,), sigdigits=4)
"test_p1=3.5e-6"
julia> savename("test", (p1=3.4999e-6,), sigdigits=4)
"test_p1=3.5e-6"
It would probably be more robust to use string formatting methods, for example the Printf.@sprintf macro, to produce the final string after using the round
function.
I am using DrWatson v2.9.1 and julia version 1.7.3.
Great! Thanks a lot for the great bug report! I agree with your suggestion for the fix, if anyone wants to do a PR this seems rather simple!
Adding Printf.@sprintf
would also be useful for when using savename to create legend or plot annotation for when I want to keep trailing zeros to make them consistent.
edit: which is a feature I would like.
Hello, I tried working on this issue, making changes to the valtostring(val, digits, sigdigits)
but I am unable to figure out an error. Can anyone please help me through it?
How do I pass a variable to the format string in @sprintf
?
It works for constants, and solving this error/finding an alternative should solve this issue.
I am currently doing the following:
@sprintf("%.$(digits)f", val)
Which results in:
ERROR: LoadError: ArgumentError: First argument to `@sprintf` must be a format string.
Stacktrace:
[1] var"@sprintf"(__source__::LineNumberNode, __module__::Module, fmt::Any, args::Vararg{Any})
@ Printf C:\Users\Adarsh\AppData\Local\Programs\Julia-1.10.0\share\julia\stdlib\v1.10\Printf\src\Printf.jl:1030
[2] include(mod::Module, _path::String)
@ Base .\Base.jl:495
[3] include(x::String)
@ DrWatson C:\ADARSH\Julia\DrWatson.jl\src\DrWatson.jl:2
[4] top-level scope
@ C:\ADARSH\Julia\DrWatson.jl\src\DrWatson.jl:21
[5] include
@ Base .\Base.jl:495 [inlined]
[6] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
@ Base .\loading.jl:2216
[7] top-level scope
@ stdin:3
in expression starting at C:\ADARSH\Julia\DrWatson.jl\src\naming.jl:169
in expression starting at C:\ADARSH\Julia\DrWatson.jl\src\naming.jl:160
in expression starting at C:\ADARSH\Julia\DrWatson.jl\src\DrWatson.jl:1
in expression starting at stdin:
Stacktrace:
[1] pkgerror(msg::String)
@ Pkg.Types C:\Users\Adarsh\AppData\Local\Programs\Julia-1.10.0\share\julia\stdlib\v1.10\Pkg\src\Types.jl:70
[2] precompile(ctx::Pkg.Types.Context, pkgs::Vector{Pkg.Types.PackageSpec}; internal_call::Bool, strict::Bool, warn_loaded::Bool, already_instantiated::Bool, timing::Bool, _from_loading::Bool, kwargs::@Kwargs{io::Base.TTY})
@ Pkg.API C:\Users\Adarsh\AppData\Local\Programs\Julia-1.10.0\share\julia\stdlib\v1.10\Pkg\src\API.jl:1656
[3] precompile(pkgs::Vector{Pkg.Types.PackageSpec}; io::Base.TTY, kwargs::@Kwargs{_from_loading::Bool})
@ Pkg.API C:\Users\Adarsh\AppData\Local\Programs\Julia-1.10.0\share\julia\stdlib\v1.10\Pkg\src\API.jl:159
[4] precompile
@ Pkg.API C:\Users\Adarsh\AppData\Local\Programs\Julia-1.10.0\share\julia\stdlib\v1.10\Pkg\src\API.jl:147 [inlined]
[5] #precompile#114
@ Pkg.API C:\Users\Adarsh\AppData\Local\Programs\Julia-1.10.0\share\julia\stdlib\v1.10\Pkg\src\API.jl:146 [inlined]
[6] #invokelatest#2
@ Base .\essentials.jl:889 [inlined]
[7] invokelatest
@ Base .\essentials.jl:884 [inlined]
[8] _require(pkg::Base.PkgId, env::String)
@ Base .\loading.jl:1957
[9] __require_prelocked(uuidkey::Base.PkgId, env::String)
@ Base .\loading.jl:1806
[10] #invoke_in_world#3
@ Base .\essentials.jl:921 [inlined]
[11] invoke_in_world
@ Base .\essentials.jl:918 [inlined]
[12] _require_prelocked(uuidkey::Base.PkgId, env::String)
@ Base .\loading.jl:1797
[13] macro expansion
@ Base .\loading.jl:1784 [inlined]
[14] macro expansion
@ Base .\lock.jl:267 [inlined]
[15] __require(into::Module, mod::Symbol)
@ Base .\loading.jl:1747
[16] #invoke_in_world#3
@ Base .\essentials.jl:921 [inlined]
[17] invoke_in_world
@ Base .\essentials.jl:918 [inlined]
[18] require(into::Module, mod::Symbol)
@ Base .\loading.jl:1740
What can be the way out here? Is there an alternative method?