JuliaPhysics / Measurements.jl

Error propagation calculator and library for physical measurements. It supports real and complex numbers with uncertainty, arbitrary precision calculations, operations with arrays, and numerical integration.

Home Page:https://juliaphysics.github.io/Measurements.jl/stable/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to print with more as 3 digits?

MartinOtter opened this issue · comments

In the following example:

using Measurements;
a = 1.23456789012345 ± 0.123456789012345
println("a = $a")

# results in :
a = 1.23 ± 0.12

Sorry, but I did not find a way to easily print a measurement variable with more as 3 digits.

That's kind of similar to #5. I don't know any handy way to select the output format.

What you can very manually do is

julia> println("a = $(round(Measurements.value(a); digits=3)) ± $(round(Measurements.uncertainty(a); digits=3))")
a = 1.235 ± 0.123

I know this isn't great, but if you have concrete suggestions about how to control formatting, please share.

I understand that for "usual" output the number of shown digits needs to be related to the digits of the uncertainty. I need it for unit testing (so all digits should be shown). Here is a rough way how this could be accomplished (in order that I can test it, I introduced MyMeasurement):

module TestShow

using Measurements

mutable struct MyMeasurement
   v::Measurement{Float64}
end

v1 = 1.23456789012345 ± 0.123456789012345
v2 = MyMeasurement(v1)

function Base.show(io::IO, m::MyMeasurement)
   compact = get(io, :compact, missing)
   if ismissing(compact)  
      # your current method
      # (the following lines are just for testing and would have to be replaced with your current method)
       println(io, "Compact representation (needs to be adapted):")
       Base.show(io, Measurements.value(m.v))
       print(io, " ± ")
       Base.show(io, Measurements.uncertainty(m.v))
   else
       println(io, "Standard representation of Float numbers")
       Base.show(io, Measurements.value(m.v))
       print(io, " ± ")
       Base.show(io, Measurements.uncertainty(m.v))
   end
   
   return nothing
end

stdout1 = IOContext(stdout, :compact => true)
stdout2 = IOContext(stdout, :compact => false)

show(stdout , v2); println("\n")
show(stdout1, v2); println("\n")
show(stdout2, v2); println("\n")

println(stdout , "Via print: ", v2, "\n")
println(stdout1, "Via print: ", v2, "\n")
println(stdout2, "Via print: ", v2, "\n")

end

This results in the following output:

Compact representation (needs to be adapted):
1.23456789012345 ± 0.123456789012345

Standard representation of Float numbers
1.23457 ± 0.123457

Standard representation of Float numbers
1.23456789012345 ± 0.123456789012345

Via print: Compact representation (needs to be adapted):
1.23456789012345 ± 0.123456789012345

Via print: Standard representation of Float numbers
1.23457 ± 0.123457

Via print: Standard representation of Float numbers
1.23456789012345 ± 0.123456789012345

The user has then the choice to get 3 digits as default, or the standard 6 digits if :compact=true or 16 digits if compact=false.

Unfortunately, it seems that interpolation ignores the setting of :compact:

println(stdout2, "Via print: $v2\n")

@MartinOtter would you be happy with something like

julia> using Measurements

julia> a = 1.23456789012345 ± 0.123456789012345
1.23 ± 0.12

julia> println(IOContext(stdout, :error_digits=>3), a)
1.235 ± 0.123

julia> println(IOContext(stdout, :error_digits=>4), a)
1.2346 ± 0.1235

julia> println(IOContext(stdout, :error_digits=>5), a)
1.23457 ± 0.12346

julia> println(IOContext(stdout, :error_digits=>6), a)
1.234568 ± 0.123457

?

Good solution