# Bug with isapprox?

#1

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?

#2

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
``````

#3

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?

#4

#5

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` `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`.

#6

I stand corrected. Thanks for chiming in!

#7

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=ε)`.