Skip to content

Uncertain decimal literal 0.03?3 loses its exact zero endpoint #785

Open

Description

@vera-rubin

Parsing 0.03?3 gives a positive lower endpoint instead of [0, 3/50]. I"0.03?3" gives the same bounds.

Version: IntervalArithmetic.jl 1.0.12, 8453a776432fbdde32a9edc3cb15da82eb9b3418, Julia 1.10.10 and 1.12.7, Linux 6.17.0-1020-oracle x86_64.

Both forms give these bounds on both Julia versions at default precision: Float64 endpoints, 256-bit BigFloat. Run in a fresh directory with Julia 1.10.10 on PATH:

git clone https://github.com/JuliaIntervals/IntervalArithmetic.jl.git
git -C IntervalArithmetic.jl checkout --detach 8453a776432fbdde32a9edc3cb15da82eb9b3418
julia --startup-file=no --project=env -e 'using Pkg; Pkg.develop(path="IntervalArithmetic.jl"); Pkg.add([PackageSpec(name="CRlibm", version="1.0.2"), PackageSpec(name="CoreMath", version="0.1.0"), PackageSpec(name="RoundingEmulator", version="0.2.1")])'
cat > repro.jl <<'JULIA'
# CC0-1.0
using IntervalArithmetic, Test

x = parse(Interval{Float64}, "0.03?3")
expected = (0.0, Float64(big(3)//50, RoundUp))
println("actual   ", bounds(x))
println("expected ", expected)
println("control  ", bounds(parse(Interval{Float64}, "[0,0.06]")))
@test bounds(x) == expected
JULIA
OPENBLAS_NUM_THREADS=1 julia -O3 --startup-file=no --threads=1 --project=env repro.jl

Actual: (2.698802673467014e-79, 0.060000000000000005). The assertion fails. Control: (0.0, 0.060000000000000005).

The parser contract requires tight enclosure and defines uncertainty in last-digit units. 3/100 ± 3/100 requires Float64 bounds (0.0, 0.060000000000000005).

The uncertain branch appears to round midpoint and decimal unit separately in BigFloat before subtracting and converting outward.

Related IEEE Std 1788-2015 clauses: 12.11.1, 12.11.3 (uncertain form (c)), 12.12.7. We rely on the package contract because the published IEEE body was unavailable.

Happy to send a PR.

— ChipLab

Activity

  1. Kolaru commented on Oct 14, 2026

    @Kolaru
    Member

    Yep, that's a bug.

    julia> x = I"0.03?3"
    [2.6988e-79, 0.06]_com

    It feels like such parsing is a good use case for Rational, as everything involved here is exactly representable as Rational e.g. "0.03?3" has the form 3//100 +- 3 * 1//100. That way, the question of rounding is solved, and it just need to be applied at the last step to convert to Float64.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions