Skip to content

bump slop for twiceprecision division #59140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

oscardssmith
Copy link
Member

division (unlike the other intrinsics) can have table-maker dilema problems since the true result has infinite bits. Bumping the slop for it by 1 reduces failures from 80 in 10^10 to <1 in 10^11.

I think accepting an extra bit of inaccuracy is reasonable here (the alternative would be to make the division do an extra loop and do some extra extended precision, which seems unlikely to be worth it.

fixes #23497

@oscardssmith
Copy link
Member Author

tests were done with the following code: (using QuadMath rather than BigFloat to make the tests run faster)

using Quadmath

asbits(x) = reinterpret(Unsigned, x)

asww(x) = Float128(x.hi) + Float128(x.lo)
astuple(x) = (x.hi, x.lo)

function cmp_sn2(w, hi, lo, slopbits=0)
    if !isfinite(hi)
        if abs(w) > floatmax(typeof(hi))
            return isinf(hi) && sign(w) == sign(hi)
        end
        if isnan(w) && isnan(hi)
            return true
        end
        return w == hi
    end
    if abs(w) < nextfloat(zero(hi))
        return (hi == zero(hi) || abs(w - widen(hi)) < abs(w)) && lo == zero(hi)
    end
    z = widen(hi) + widen(lo)
    w == z && return true
    zu, wu = asbits(z), asbits(w)
    tz = trailing_zeros(zu)
    zu >>= tz
    wu >>= tz
    zu = zu >> slopbits
    wu = wu >> slopbits
    return wu - 1 <= zu <= wu + 1
end

function test_twice(n, slopbits=5)
    Threads.@threads for i = 1:n
        T = Float32
        Tw = widen(T)
        x = Base.TwicePrecision{T}(rand())
        y = Base.TwicePrecision{T}(rand())
        xw, yw = asww(x), asww(y)
        if !cmp_sn2(Float64(xw/yw), astuple(x/y)..., slopbits)
            println((x,y))
        end
    end
    return
end

@giordano giordano added test This change adds or pertains to unit tests ranges Everything AbstractRange labels Jul 29, 2025
@giordano
Copy link
Member

Why is CI not starting on this PR?

@JeffBezanson JeffBezanson merged commit 884c5e3 into JuliaLang:master Jul 30, 2025
7 of 10 checks passed
@oscardssmith oscardssmith deleted the os/fix-TwicePrecision-division branch July 30, 2025 19:00
@@ -230,7 +230,7 @@ end
@test cmp_sn2(Tw(xw+yw), astuple(x+y)..., slopbits)
@test cmp_sn2(Tw(xw-yw), astuple(x-y)..., slopbits)
@test cmp_sn2(Tw(xw*yw), astuple(x*y)..., slopbits)
@test cmp_sn2(Tw(xw/yw), astuple(x/y)..., slopbits)
@test cmp_sn2(Tw(xw/yw), astuple(x/y)..., slopbits+1) # extra bit because division is hard
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I really dislike vague-posting comments like this. The PR description is much more informative. Of course it's possible to find the PR with git blame, but let's please be precise where we can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ranges Everything AbstractRange test This change adds or pertains to unit tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fuzzing test failure with TwicePrecision in test/ranges.jl
4 participants