DoubleFloats.jl
DoubleFloats.jl copied to clipboard
isapprox is incorrect for tolerances beyond standard precision
The following is incorrect:
julia> T = Double64
Double64 (alias for DoubleFloat{Float64})
julia> x = Double64(0.9, 1e-20)
9.00000000000000022214460492503130852e-01
julia> abs(x - T(9)/10)
2.22144604925031320405193304841894479e-17
julia> isapprox(x, T(9)/10; rtol=1e-22, atol=1e-22)
true
If I understand the internals, the isapprox function uses HI(x)===HI(y) as a shortcut for the test, which doesn't look right.
What would you recommend?
On Mon, Aug 5, 2024 at 3:07 PM Toby Driscoll @.***> wrote:
The following is incorrect:
julia> T = Double64 Double64 (alias for DoubleFloat{Float64})
julia> x = Double64(0.9, 1e-20)9.00000000000000022214460492503130852e-01
julia> abs(x - T(9)/10)2.22144604925031320405193304841894479e-17
julia> isapprox(x, T(9)/10; rtol=1e-22, atol=1e-22)true
If I understand the internals, the isapprox function uses HI(x)===HI(y) as a shortcut for the test, which doesn't look right.
— Reply to this email directly, view it on GitHub https://github.com/JuliaMath/DoubleFloats.jl/issues/206, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAM2VRTX44G3MBTT3DCZMETZP7EORAVCNFSM6AAAAABMA3T4U6VHI2DSMVQWIX3LMV43ASLTON2WKOZSGQ2DSMRYGAYTGNQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>
The most straightforward thing would be to remove HI(x) === HI(y) || from line 20 of misc.jl. I suppose you could keep it by pairing it with a test that rtol is large enough, but I'm skeptical that the potential time savings is worth very much.
And then. of course, adding some relevant unit tests. 😁
anyplace that HI(x) is appropriate to be used in place of (x) it should be -- the internals of a full isapprox evaluation in Double64s is more involved .. once that happens is everything tends to intermix and that can extend runtimes (just my experience)
On Tue, Aug 6, 2024 at 10:13 AM Toby Driscoll @.***> wrote:
The most straightforward thing would be to remove HI(x) === HI(y) || from line 20 of misc.jl. I suppose you could keep it by pairing it with a test that rtol is large enough, but I'm skeptical that the potential time savings is worth very much.
And then. of course, adding some relevant unit tests. 😁
— Reply to this email directly, view it on GitHub https://github.com/JuliaMath/DoubleFloats.jl/issues/206#issuecomment-2271402334, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAM2VRRCYWQPILS3KPDE77DZQDKZ5AVCNFSM6AAAAABMA3T4U6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZRGQYDEMZTGQ . You are receiving this because you commented.Message ID: @.***>
OK, if the HI parts of x and y are the same, then x-y is equal to x.lo-y.lo, right? So that's cheap.
But I don't know if you can cheat on the rtol*max(abs(x), abs(y)) part if rtol is specified in the same precision as x and y. The chances that you would care about the difference between using, say, abs(x) and abs(x.hi) there seem remote, but you can probably invent a pathological counterexample that would break the implied guarantee.