# Inconsistency of NaN

**URL:** <https://discourse.julialang.org/t/inconsistency-of-nan/28671>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [September 11, 2019, 11:33pm UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671 "2019-09-11T23:33:11Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![aerdely](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aerdely/32/37506_2.png) [@aerdely](https://discourse.julialang.org/u/aerdely)\
**Post date:** [September 11, 2019, 11:33pm UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/1 "2019-09-11T23:33:11Z")

</div>

`0/0` returns `NaN`  
`NaN*false` returns `0.0`  
`(0/0)*false` returns `-0.0`  
Isn’t this an inconsistency of NaN? 🤔  
Also:  
`julia> (NaN*(0/0))*false`  
`0.0`  
but:  
`julia> ((0/0)*NaN)*false`  
`-0.0`  
🤔

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [September 11, 2019, 11:44pm UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/2 "2019-09-11T23:44:40Z")

</div>

It appears that these are two different bit values although they both print as `NaN`

```nohighlight
julia> reinterpret(UInt,0/0)
0xfff8000000000000

julia> reinterpret(UInt,NaN)
0x7ff8000000000000

julia> 0/0 == NaN
false

```

they differ only by a single bit, presumably the sign bit

---

<div class="post-metadata">

**Author:** ![aerdely](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aerdely/32/37506_2.png) [@aerdely](https://discourse.julialang.org/u/aerdely)\
**Post date:** [September 11, 2019, 11:54pm UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/4 "2019-09-11T23:54:28Z")

</div>

Ok, but:  
`julia> 0.0 == -0.0`  
`true`  
😬  
though:  
`julia> 0.0 === -0.0`  
`false`

---

<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:** [September 12, 2019, 12:36am UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/5 "2019-09-12T00:36:37Z")

</div>

so at least

```julia
julia> (0/0)*false == NaN*false
true

```

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [September 12, 2019, 12:37am UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/6 "2019-09-12T00:37:53Z")

</div>

That’s correct, they can’t be _egal_ (`===`) because the sign bit is different:

```julia
julia> reinterpret(UInt, 0.0)
0x0000000000000000

julia> reinterpret(UInt, -0.0)
0x8000000000000000

```

or

```julia
julia> bitstring(0.0)
"0000000000000000000000000000000000000000000000000000000000000000"

julia> bitstring(-0.0)
"1000000000000000000000000000000000000000000000000000000000000000"

```

---

<div class="post-metadata">

**Author:** ![aerdely](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aerdely/32/37506_2.png) [@aerdely](https://discourse.julialang.org/u/aerdely)\
**Post date:** [September 12, 2019, 1:16am UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/8 "2019-09-12T01:16:04Z")

</div>

Ok, and what about:  
`julia> (NaN*(0/0))*false`  
`0.0`  
but:  
`julia> ((0/0)*NaN)*false`  
`-0.0`  
🤔

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [September 12, 2019, 4:19am UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/10 "2019-09-12T04:19:22Z")

</div>

In [IEEE-754](https://en.wikipedia.org/wiki/Ieee_float), the IEEE standard for floating point arithmetic, which Julia and most other languages use, `NaN`s are encoded with the [exponent field filled with ones](https://en.wikipedia.org/wiki/NaN#Floating_point). According to the standard, the sign bit does not matter for determining `NaN`ness, and the sign bit is precisely what’s different between `0/0` and `NaN`. I’m not sure exactly why `0/0` results in a different sign bit, but it could well just be an implementation detail. Next, there’s the multiplication with the `Bool` `false`, which (eventually) hits this method:

[https://github.com/JuliaLang/julia/blob/47f2800747e65df2720429436b94dc58a9fcb22c/base/bool.jl#L109-L111](https://github.com/JuliaLang/julia/blob/47f2800747e65df2720429436b94dc58a9fcb22c/base/bool.jl#L109-L111)

The `copysign` is what causes the sign bit of the `NaN` to appear in the final result. I’m not sure whether that’s intended. I suppose it is a little weird that information that’s supposed to be (mostly) immaterial has an observable effect here. Then again, it seems harmless.

---

<div class="post-metadata">

**Author:** ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)\
**Post date:** [September 12, 2019, 6:14am UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/11 "2019-09-12T06:14:13Z")

</div>

> [@tkoolen](#):
>
> According to the standard, the sign bit does not matter for determining `NaN` ness, and the sign bit is precisely what’s different between `0/0` and `NaN` .

Why is why the way to determine `NaN`ness is to use `isnan` and not any number of consecutive `=`'s. You’re not supposed to do `0/0 == NaN` to check if the lhs is `NaN`.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [September 12, 2019, 7:10am UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/12 "2019-09-12T07:10:28Z")

</div>

or use `haskey`

```julia
julia> haskey(Dict(NaN => nothing), 0/0)
true

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 12, 2019, 7:11am UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/13 "2019-09-12T07:11:11Z")

</div>

There are several things to unpack in this post.

1. `false*NaN` is special cased to make `false` “strong”, see [the implementation](https://github.com/JuliaLang/julia/blob/47f2800747e65df2720429436b94dc58a9fcb22c/base/bool.jl#L109)

2. but the `copysign` method for `NaN`s is a bit misleading, as `NaN`s are not supposed to have a sign:

3. `(NaN*(0/0))*false` is the same phenomenon, except the sign bit comes from the first operand.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [September 12, 2019, 1:16pm UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/14 "2019-09-12T13:16:11Z")

</div>

> [@tkoolen](#):
>
> I’m not sure exactly why `0/0` results in a different sign bit, but it could well just be an implementation detail.

It’s what the hardware does, iirc.

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [September 12, 2019, 2:57pm UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/15 "2019-09-12T14:57:53Z")

</div>

> [@tkf](#):
>
> or use `haskey`
> 
> ```julia
> julia> haskey(Dict(NaN => nothing), 0/0)
> true
> 
> ```

Or rather `isequal` (which is what `haskey` uses): `isequal(NaN, 0/0) == true`.

---

<div class="post-metadata">

**Author:** ![loisel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/loisel/32/50626_2.png) [@loisel](https://discourse.julialang.org/u/loisel)\
**Post date:** [September 13, 2019, 12:30pm UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/16 "2019-09-13T12:30:06Z")

</div>

Whoa there. I don’t know if these are officially bugs but they are at odds with the IEEE 754 spec, which reads in part:

> For an operation with quiet NaN inputs, other than maximum and minimum operations, if a floating-point result is to be delivered the result shall be a quiet NaN which should be one of the input NaNs.

See here: [http://irem.univ-reunion.fr/IMG/pdf/ieee-754-2008.pdf](http://irem.univ-reunion.fr/IMG/pdf/ieee-754-2008.pdf)

I understand why people usually want false\*x to be falsy but NaN is falsy enough and more correct than 0.0 for false\*NaN.

---

<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:** [September 13, 2019, 12:56pm UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/17 "2019-09-13T12:56:24Z")

</div>

I agree. But since this has been in the language for a while, I think a lot of programmers (myself included) use `false*x` on uninitialized data and expect to get rid of `NaN`s that way.

I think it would be nice if Julia had a “strong zero” in a type of its own. I even wrote a package implementing that a while back (though I never registered it or upgraded it to be 1.0 compatible.)

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [September 13, 2019, 2:59pm UTC](https://discourse.julialang.org/t/inconsistency-of-nan/28671/18 "2019-09-13T14:59:36Z")

</div>

I think the argument is that IEEE-754 does not pertain to operations involving boolean inputs. I’m not picking sides on whether or not the current behavior of various operations with mixed floating point number and boolean inputs is ‘right’, but it’s not a clear-cut case.
