Reporting a Result
A propagated measurement is not yet a reported one. JCGM 100:2008 §7 governs how a result is written down, and what it says is more prescriptive than most software admits: there are four acceptable textual forms, a rule for how many digits to quote, and a separate statement for expanded uncertainty that must name its coverage factor.
report produces them.
The four forms of §7.2.2
The GUM's own worked example is a 100 g mass standard whose calibration gives m_S = 100.02147 g with u_c = 0.35 mg:
using SymbolicUncertainties
report(100.02147, 0.00035; symbol = "m_S", unit = "g")Measurement result — JCGM 100:2008 §7.2.2
m_S = 100.02147 g with u_c = 0.00035 g
m_S = 100.02147(35) g
m_S = 100.02147(0.00035) g
m_S = (100.02147 ± 0.00035) g
All four say the same thing. Which one belongs on a certificate is a house-style question, not a metrological one.
A SymbolicMeasurement prints as val ± err because that is the Julia ecosystem convention, set by Measurements.jl. §7.2.2 deliberately avoids the glyph: ± is read as an expanded uncertainty y ± U (§6.2), and a combined standard uncertainty is a different quantity by a factor of k. The fourth form above uses ± only because the surrounding text says the number is u_c.
Do not copy a ± display into a calibration certificate. That is what this page exists to prevent.
How many digits — §7.2.6
u_c is quoted to two significant digits, and the estimate is rounded to that same last significant place. Quoting an estimate to more digits than its uncertainty supports claims a precision the measurement does not have; quoting fewer discards information that was paid for.
The rule is on significant digits of the uncertainty, not on decimal places, so a coarse uncertainty coarsens the estimate with it:
report(1234.5678, 12.0; symbol = "y", unit = "m").forms[4]"y = (1235 ± 12) m"Feeding in more digits than the uncertainty can carry changes nothing:
report(100.021473829, 0.000351119; symbol = "m_S", unit = "g").forms[2]"m_S = 100.02147(35) g"Pass digits = 1 or digits = 3 where a laboratory's own convention differs; §7.2.6 says "at most two" and leaves room.
Expanded uncertainty — §7.2.4
An expanded uncertainty is a different statement, not an annotation of the standard one, and §7.2.4 asks it to name its coverage factor and the basis for it. Supplying k produces it:
report(
100.02147, 0.00035;
symbol = "m_S",
unit = "g",
k = 2.26,
coverage_probability = 0.95,
dof = 9,
)Measurement result — JCGM 100:2008 §7.2.2
m_S = 100.02147 g with u_c = 0.00035 g
m_S = 100.02147(35) g
m_S = 100.02147(0.00035) g
m_S = (100.02147 ± 0.00035) g
Expanded uncertainty — §7.2.4
m_S = (100.02147 ± 0.00079) g, where the number following the symbol ± is the numerical value of an expanded uncertainty U = k·u_c, with U determined from a combined standard uncertainty u_c = 0.00035 g and a coverage factor k = 2.26 based on the t-distribution for ν = 9 degrees of freedom, and defines an interval estimated to have a level of confidence of 95 percent.
Without k there is no expanded statement to make, and the expanded field is nothing. ± U with no stated k is precisely the ambiguity §7.2.2 warns about, so the package will not write one.
From a model, with units
With DynamicQuantities loaded, report(m, values) takes the measurement and unit-carrying values, and derives the numbers and the unit from the model — the same walk evaluate uses:
using Symbolics, DynamicQuantities
@variables V I σV σI
R = (V ± σV) / (I ± σI)
readings = Dict(
V => 10.000us"V", σV => 1e-3us"V",
I => 0.10002us"A", σI => 1e-5us"A",
)
report(R, readings; symbol = "R", unit = "Ω", k = 2, coverage_probability = 0.95)Measurement result — JCGM 100:2008 §7.2.2
R = 99.980 Ω with u_c = 0.014 Ω
R = 99.980(14) Ω
R = 99.980(0.014) Ω
R = (99.980 ± 0.014) Ω
Expanded uncertainty — §7.2.4
R = (99.980 ± 0.028) Ω, where the number following the symbol ± is the numerical value of an expanded uncertainty U = k·u_c, with U determined from a combined standard uncertainty u_c = 0.014 Ω and a coverage factor k = 2, and defines an interval estimated to have a level of confidence of 95 percent.
The dimensional walk composes what it is given, so this model produces A⁻¹ V. report recognises the thirteen coherent derived SI units by their dimension and writes Ω instead — likewise W for A V, and Hz for s⁻¹. The unit = "Ω" above is therefore redundant here, and kept only to show the override.
Two limits on that naming, both deliberate.
A prefixed unit is never renamed. 1 kΩ expands to a thousand base units, so a result computed in kilohms stays in kilohms: calling it Ω would be wrong by a factor of a thousand. Only a unit that is already the coherent SI one is given its name.
A dimension does not determine a kind of quantity (VIM §1.1). Torque and energy are both m² kg s⁻², so the table calls that J and a torque must say otherwise:
@variables F σF d σd
M = (F ± σF) * (d ± σd)
vals = Dict(
F => 12.0us"N", σF => 0.1us"N",
d => 0.25us"m", σd => 0.001us"m",
)
(
default = report(M, vals; symbol = "M").forms[2],
corrected = report(M, vals; symbol = "M", unit = "N m").forms[2],
)(default = "M = 3.000(28) J", corrected = "M = 3.000(28) N m")Hz carries the same caveat, sharing s⁻¹ with an activity in becquerel. check_units refuses to unify such homonyms through Kind; report cannot make that distinction on its own, because a product of two plain quantities carries no kind to propagate — which is exactly why unit exists.
API reference
SymbolicUncertainties.report — Function
report(y, u; symbol, unit, digits, k, coverage_probability, dof)
report(m::SymbolicMeasurement; kwargs...)Render a measurement result in the textual forms of JCGM 100:2008 §7.2, returning an UncertaintyReport.
± is not one of them by default. §7.2.2 avoids the glyph because it is read as an expanded uncertainty y ± U; the fourth form uses it only with the explicit statement that the number is u_c.
Arguments
y,u— the estimate and its combined standard uncertainty, as plain reals. WithDynamicQuantitiesloaded,report(m, values)takes a measurement and unit-carrying values instead, and derives both the numbers and the unit from the model.symbol(keyword, default"y") — the measurand's name.unit(keyword, default"") — the unit, written as it should appear.digits(keyword, default2) — significant digits kept onu_c, per §7.2.6. The estimate is rounded to the same last place.k,coverage_probability,dof(keywords, defaultnothing) — supplykto also produce the §7.2.4 expanded-uncertainty statement, withU = k·u_c. The other two are named in the text when given; §7.2.4 asks for both, since± Uwithout them is the ambiguity §7.2.2 warns about.
Example
The GUM's own worked example, a 100 g mass standard:
julia> r = report(100.02147, 0.00035; symbol = "m_S", unit = "g");
julia> r.forms[2]
"m_S = 100.02147(35) g"Traces REQ-239. Implements JCGM 100:2008 §7.2.2, §7.2.4 and §7.2.6.
SymbolicUncertainties.UncertaintyReport — Type
UncertaintyReportA measurement result rendered in the textual forms JCGM 100:2008 §7.2 prescribes. Produced by report; printing it shows every form.
Fields
symbol— the name of the measurand as it appears in the text.value,uncertainty— the rounded estimate and combined standard uncertainty, in the unit ofunit.unit— the unit as it is written,""for a dimensionless result.digits— significant digits kept onu_c(§7.2.6).forms— the four §7.2.2 renderings, in the standard's own order.expanded— the §7.2.4 statement, ornothingwhen no coverage factor was supplied. There is no expanded uncertainty without a statedk.
Traces REQ-239.