elm/core

NaN compares as equal to zero in several cases involving literal 0

ianmackenzie opened this issue · 1 comments

In Elm 0.19.1, it seems that the special case of x == 0 is compiled to !x in the generated JavaScript, but this means that if x is NaN then x == 0 will return True. Given

module Main exposing (main)

import Html exposing (Html)


check : String -> Bool -> Html Never
check string result =
    let
        resultString =
            if result then
                "True"

            else
                "False"
    in
    Html.div [] [ Html.text (string ++ ": " ++ resultString) ]


type Wrapper a
    = Wrapper a


main : Html Never
main =
    let
        zero =
            0

        nan =
            0 / 0
    in
    Html.div []
        [ check "0 == 0 / 0" (0 == 0 / 0)
        , check "0 / 0 == 0" (0 / 0 == 0)
        , check "1 == 0 / 0" (1 == 0 / 0)
        , check "0 / 0 == 1" (0 / 0 == 1)
        , check "nan == 0" (nan == 0)
        , check "0 == nan" (0 == nan)
        , check "nan == zero" (nan == zero)
        , check "zero == nan" (zero == nan)
        , check "Wrapper 0 == Wrapper (0 / 0)" (Wrapper 0 == Wrapper (0 / 0))
        , check "Wrapper (0 / 0) == Wrapper 0" (Wrapper (0 / 0) == Wrapper 0)
        , check "Wrapper nan == Wrapper zero" (Wrapper nan == Wrapper zero)
        , check "Wrapper zero == Wrapper nan" (Wrapper zero == Wrapper nan)
        ]

I would expect all the checks to return False, but in a debug build I get

0 == 0 / 0: True
0 / 0 == 0: True
1 == 0 / 0: False
0 / 0 == 1: False
nan == 0: True
0 == nan: True
nan == zero: False
zero == nan: False
Wrapper 0 == Wrapper (0 / 0): False
Wrapper (0 / 0) == Wrapper 0: False
Wrapper nan == Wrapper zero: False
Wrapper zero == Wrapper nan: False

and in an optimized build I get

0 == 0 / 0: True
0 / 0 == 0: True
1 == 0 / 0: False
0 / 0 == 1: False
nan == 0: True
0 == nan: True
nan == zero: False
zero == nan: False
Wrapper 0 == Wrapper (0 / 0): True
Wrapper (0 / 0) == Wrapper 0: True
Wrapper nan == Wrapper zero: False
Wrapper zero == Wrapper nan: False

Note that comparisons work properly when using the variable zero instead of the literal 0, and wrapped literals compare as expected in debug builds but not in optimized builds where the wrapper is optimized away.

Thanks for reporting this! To set expectations:

  • Issues are reviewed in batches, so it can take some time to get a response.
  • Ask questions a community forum. You will get an answer quicker that way!
  • If you experience something similar, open a new issue. We like duplicates.

Finally, please be patient with the core team. They are trying their best with limited resources.