There are three equality operators: `==`

, `===`

, and `isequal`

. (The last is not really an operator, but it is a function and all operators are functions.)

`==`

`==`

is *value* equality. It returns `true`

when two objects represent, in their present state, the same value.

For instance, it is obvious that

```
julia> 1 == 1
true
```

but furthermore

```
julia> 1 == 1.0
true
julia> 1 == 1.0 + 0.0im
true
julia> 1 == 1//1
true
```

The right hand sides of each equality above are of a different type, but they still represent the same value.

For mutable objects, like arrays, `==`

compares their present value.

```
julia> A = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> B = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> C = [1, 3, 2]
3-element Array{Int64,1}:
1
3
2
julia> A == B
true
julia> A == C
false
julia> A[2], A[3] = A[3], A[2] # swap 2nd and 3rd elements of A
(3,2)
julia> A
3-element Array{Int64,1}:
1
3
2
julia> A == B
false
julia> A == C
true
```

Most of the time, `==`

is the right choice.

`===`

`===`

is a far stricter operation than `==`

. Instead of value equality, it measures egality. Two objects are egal if they cannot be distinguished from each other by the program itself. Thus we have

```
julia> 1 === 1
true
```

as there is no way to tell a `1`

apart from another `1`

. But

```
julia> 1 === 1.0
false
```

because although `1`

and `1.0`

are the same value, they are of different types, and so the program can tell them apart.

Furthermore,

```
julia> A = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> B = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> A === B
false
julia> A === A
true
```

which may at first seem surprising! How could the program distinguish between the two vectors `A`

and `B`

? Because vectors are mutable, it could modify `A`

, and then it would behave differently from `B`

. But no matter how it modifies `A`

, `A`

will always behave the same as `A`

itself. So `A`

is egal to `A`

, but not egal to `B`

.

Continuing along this vein, observe

```
julia> C = A
3-element Array{Int64,1}:
1
2
3
julia> A === C
true
```

By assigning `A`

to `C`

, we say that `C`

has *aliased* `A`

. That is, it has become just another name for `A`

. Any modifications done to `A`

will be observed by `C`

also. Therefore, there is no way to tell the difference between `A`

and `C`

, so they are egal.

`isequal`

The difference between `==`

and `isequal`

is very subtle. The biggest difference is in how floating point numbers are handled:

```
julia> NaN == NaN
false
```

This possibly surprising result is defined by the IEEE standard for floating point types (IEEE-754). But this is not useful in some cases, such as sorting. `isequal`

is provided for those cases:

```
julia> isequal(NaN, NaN)
true
```

On the flip side of the spectrum, `==`

treats IEEE negative zero and positive zero as the same value (also as specified by IEEE-754). These values have distinct representations in memory, however.

```
julia> 0.0
0.0
julia> -0.0
-0.0
julia> 0.0 == -0.0
true
```

Again for sorting purposes, `isequal`

distinguishes between them.

```
julia> isequal(0.0, -0.0)
false
```