Guaranteed intervals
A guaranteed interval is a concept distinct from decorations (see Decorations) and not specified in the IEEE 1788-2015 standard. It is introduced to accommodate Julia’s flexible system of type conversion and promotion, while retaining reliability in computations.
"NG" label
An interval x
constructed via interval
satisfies isguaranteed(x) == true
. However, if a call to convert(::Type{<:Interval}, ::Real)
occurs, then the resulting interval x
satisfies isguaranteed(x) == false
, receiving the "NG" (not guaranteed) label.
For instance, consider the following examples:
julia> using IntervalArithmetic
julia> setdisplay(; sigdigits = 6)
Display options: - format: full - decorations: true (ignored) - NG flag: true (ignored) - significant digits: 6 (ignored)
julia> convert(Interval{Float64}, 1.) # considered "not guaranteed" as this call can be done implicitly
Interval{Float64}(1.0, 1.0, com, false)
julia> interval(1) # considered "guaranteed" as the user explicitly constructed the interval
Interval{Float64}(1.0, 1.0, com, true)
In contrast, a BareInterval
can only be constructed via bareinterval
, it is not a subtype of Real
, and there are no allowed conversion with Number
. Thus, this interval type is always guaranteed.
Exact numbers
When typing Julia code, it is combersome to manually wrap all numerical numbers with interval
. Also, we sometimes want to use the same function for both floating-point arithmetic (maybe to check have a fast quick checks) and interval arithmetic. Then, we would want the typed-in numerical numbers to convert automatically to the appropriate numerical type depending on the context. To this end, the ExactReal
structure marks any Real
number as a user exactly typed-in value.
For instance, consider the following examples:
julia> interval(1)
Interval{Float64}(1.0, 1.0, com, true)
julia> interval(1) + ExactReal(1)
Interval{Float64}(2.0, 2.0, com, true)
julia> @exact 2interval(1) + 1 + exp(im * interval(1))
Interval{Float64}(3.5403023058681393, 3.5403023058681398, com, true) + im*Interval{Float64}(0.8414709848078965, 0.8414709848078966, com, true)
julia> @exact foo(x) = 2x + 1 + exp(im * x)
foo (generic function with 1 method)
julia> foo(1.)
3.5403023058681398 + 0.8414709848078965im
julia> foo(interval(1))
Interval{Float64}(3.5403023058681393, 3.5403023058681398, com, true) + im*Interval{Float64}(0.8414709848078965, 0.8414709848078966, com, true)