Why isn't Float32 == Float64 (Converting from Float32 to Float64)

julia> 312.09
312.09

julia> 312.09 |> Float64
312.09

julia> 312.09 |> Float64 |> Float32
312.09f0

julia> 312.09 |> Float64 |> Float32 |> Float64
312.0899963378906

julia> 312.09f0 == 312.09
false

Clearly this number exists as an Float32. But why doesn’t it convert back properly?

It doesn’t have an exact representation in either Float32 or Float64.

julia> BigFloat(312.09)
312.08999999999997498889570124447345733642578125

julia> BigFloat(312.09f0)
312.089996337890625
3 Likes
julia> bitstring(Float32(312.09))
"01000011100111000000101110000101"

julia> bitstring(Float64(312.09))
"0100000001110011100000010111000010100011110101110000101000111101"

julia> bitstring(Float64(Float32(312.09)))
"0100000001110011100000010111000010100000000000000000000000000000"

Float32 truncates an already inexact representation.

4 Likes

Thanks! Both answers are very helpful!

Note for numbers that are exactly representable in Base 2 (e.g. 1/4 or 312+3/4) your expectations are met:

julia> 312.75 |> Float32 |> Float64
312.75
6 Likes

BTW, there is no point in ‘converting’ 312.09 to Float64, since literal floats are already Float64 in the first place.

4 Likes