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`

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

.

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

.