Hi all,
I don’t understand the behavior of isapprox.
julia> -3.03664471426105e-17 ≈ 0.0
false
julia> 1.0 - 3.03664471426105e-17 ≈ 1.0 - 0.0
true
Can someone reproduce/explain what looks like a bug here?
Hi all,
I don’t understand the behavior of isapprox.
julia> -3.03664471426105e-17 ≈ 0.0
false
julia> 1.0 - 3.03664471426105e-17 ≈ 1.0 - 0.0
true
Can someone reproduce/explain what looks like a bug here?
Consider
julia> eps(0.0)
5.0e-324
julia> eps(1.0)
2.220446049250313e-16
and therefore
julia> 1.0 - 3.03664471426105e-17 == 1.0
true
I am very surprised that eps(0.0) is so small and I don’t understand why nextfloat(0.0) is 5.0e-324. Any hint?
This has nothing to do with the value of eps(0.0). x ≈ 0.0 will always give false for x ≠ 0, because ≈ tests only relative error. If x ≠ 0, then no significant digits of x match 0.0, so the result of x ≈ 0.0 is false.
In particular, x ≈ y tests norm(x-y) ≤ sqrt(eps(T))*max(norm(x),norm(y)) with T=typeof(real(x-y)), which tests whether about half of the significant digits match.
If you call isapprox(x,y) explicitly, you can pass an atol argument to instead pass an absolute tolerance, i.e. to test whether norm(x-y) ≤ atol. But since there is no reasonable way to pick a default value of atol (it is dimensionful, i.e. it depends on the scale of x and y), using ≈ sets atol to zero.
Note that 1.0 - 1e-10 ≈ 1.0 gives true, because more than half of the significant digits match 1.0.
I stand corrected. Thanks for chiming in! ![]()
If you are writing tests with the standard Test module then you can write
@test x ≈ y atol=ε
The @test macro translates that to isapprox(x, y, atol=ε).