# Why is Julia designed this way? NaN != NaN but -0.0 == 0.0

**URL:** <https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [November 11, 2021, 9:12pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350 "2021-11-11T21:12:49Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![leon](https://avatars.discourse-cdn.com/v4/letter/l/dc4da7/32.png) [@leon](https://discourse.julialang.org/u/leon)\
**Post date:** [November 11, 2021, 9:12pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/1 "2021-11-11T21:12:49Z")

</div>

I’m reading Julia’s documentation, and below are the realities:

```julia
julia> NaN == NaN
false

julia> isequal(NaN, NaN)
true

```

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

julia> isequal(-0.0, 0.0)
false

```

My data often contain NaNs, -0.0, and 0.0. IMO. This has been a major headache. Right now, I have to replace my NaNs with a special number and replace my -0.0 with 0.00001, etc. in order to avoid these issues. It would have caused so much less headache, if the below were to be true:

```julia

julia> NaN == NaN
true

julia> isequal(NaN, NaN)
true

julia> -0.0 == 0.0
true

julia> isequal(-0.0, 0.0)
true

```

Does anyone know what advantages the current design offer?

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [November 11, 2021, 9:18pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/2 "2021-11-11T21:18:17Z")

</div>

I believe it has to do with comparing value vs comparing representation in memory.

`NaN` does not have the same value as `NaN`, so `NaN == NaN` is false, but `NaN` has the same representation in memory as `NaN` so `isequal(NaN, NaN)` is true.

`-0.0` and `0.0` have the same value, but not the same representation in memory, so there it is reversed.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [November 11, 2021, 9:19pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/3 "2021-11-11T21:19:49Z")

</div>

This is according to the IEEE specification. Not really specific to Julia.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [November 11, 2021, 9:19pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/4 "2021-11-11T21:19:50Z")

</div>

Part of the answer is here:

[https://docs.julialang.org/en/v1/base/math/#Base.:==](https://docs.julialang.org/en/v1/base/math/#Base.:==)

Basically, this is the way `==` works in the float standard.

`===` is intentionally a much stricter operation: it’s only true if the computer can’t tell the difference, and `+0.0` can be separated from `-0.0` using the underlying data.

But the true answer is: a choice needs to be made, and this is the choice that was made.

---

<div class="post-metadata">

**Author:** ![leon](https://avatars.discourse-cdn.com/v4/letter/l/dc4da7/32.png) [@leon](https://discourse.julialang.org/u/leon)\
**Post date:** [November 11, 2021, 9:25pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/5 "2021-11-11T21:25:45Z")

</div>

Thanks all for the replies!

The thing is that we often do not know what some of the existing functions or packages decide to use `==` or `isequal` until errors are spotted sometimes in a hard way. Even Julia’s own `unique` function suffers from this issue as was discussed previously.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [November 11, 2021, 9:38pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/6 "2021-11-11T21:38:42Z")

</div>

Whether there are usage errors is of no consequence. The important question is _would changing it reduce the number of errors?_

I’d argue no. The current system is pretty simple, and any edge cases are the same as would be in any other system. For a majority of cases remembering the rules “`==`: equals, `===`: is identical to” will suffice.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 11, 2021, 9:38pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/7 "2021-11-11T21:38:58Z")

</div>

> [@leon](#):
>
> ```julia
> julia> -0.0 == 0.0
> true
> 
> ```

As a side note, if you are comparing floating point numbers, probably using `isapprox` is better.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [November 11, 2021, 9:45pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/8 "2021-11-11T21:45:14Z")

</div>

> [@leon](#):
>
> Even Julia’s own `unique` function suffers from this issue as was discussed previously.

that was a bug of `unique`, the behavior you’re seeing here, as explained, is specified by IEEE standard, any language that uses IEEE floating-point number has the same behavior (or they should, if they want to be comlient with IEEE…)

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 11, 2021, 10:14pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/9 "2021-11-11T22:14:19Z")

</div>

If you _really_ need that behavior to not comply with the standard in your package, define your internal comparing function, such as:

```julia
julia> function compare(x,y)
           if isnan(x) && isnan(x)
               return true
           else
               return isequal(x,y)
           end
       end
compare (generic function with 1 method)

julia> compare(NaN,NaN)
true

julia> compare(0.0,0.0)
true

```

(bad example here, since you could just use `isequal` everywhere, and that would do it, but if you need any other specific behavior, that’s the idea, if you are expecting to deal with some sort of data that needs a special attention on that side, define your own function to deal with that)

---

<div class="post-metadata">

**Author:** ![leon](https://avatars.discourse-cdn.com/v4/letter/l/dc4da7/32.png) [@leon](https://discourse.julialang.org/u/leon)\
**Post date:** [November 11, 2021, 10:47pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/10 "2021-11-11T22:47:17Z")

</div>

Understood!

Just curious why IEEE would make the decision that way. There must be some advantages they have considered I assume?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [November 11, 2021, 11:04pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/11 "2021-11-11T23:04:48Z")

</div>

Check out [Branch Cuts for Complex Elementary Functions or Much Ado About Nothing’s Sign Bit](https://people.freebsd.org/~das/kahan86branch.pdf) by Professor William Kahan. :kahan:

---

<div class="post-metadata">

**Author:** ![artkuo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/artkuo/32/28577_2.png) [@artkuo](https://discourse.julialang.org/u/artkuo)\
**Post date:** [November 11, 2021, 11:06pm UTC](https://discourse.julialang.org/t/why-is-julia-designed-this-way-nan-nan-but-0-0-0-0/71350/12 "2021-11-11T23:06:13Z")

</div>

> [@leon](#):
>
> NaNs, -0.0, and 0.0

It sounds like you are looking for sentinel values, as opposed to actual floating-point data. It’s probably better to deal with sentinels directly rather than to replace them with other sentinels such as 0.00001. As for `NaN`, the direct approach is `isnan`. You do indeed have a problem not knowing whether an existing package’s `someequalitycheck(x,y)` gets tripped up on these things, but there are two issues here. First, using _any_ equality check with float data is slightly suspect, and could potentially be re-thought (e.g., `isapprox`). Second, assuming equality is a valid thing done by the function, _don’t assume_ it can be fed `NaN` unless designed expressly to do what you want.

Yes, the IEEE standard has advantages, and [this report by Bill Kahan](https://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF) provides some context. One can debate the merits of IEEE, but I really think your first issue is dealing with sentinels appropriately.
