Can not use specific float32 values as map key

Viewed 611

Using float32 as map key returns unexpected result

package main

import "fmt"

func main() {
    result := make(map[float32]map[float32]float32)

    var t1 float32 = 1586238540
    var t2 float32 = 1586238600

    result[t1] = map[float32]float32{1:1,2:2}
    result[t2] = map[float32]float32{3:3,4:4}

    fmt.Println(result[t1])
    fmt.Println(result[t2])
}
map[3:3 4:4]
map[3:3 4:4]

Go version: go version go1.14 linux/amd64

Changing result to map[float64]map[float32]float32 and t1, t2 accordingly gives the right result.

What could be a reason for this weird behavior?

3 Answers

A 32 bit float has a 23 bit mantissa, with an implicit preceeding highest 1 bit. So the maximum value representable by the mantissa is 2²⁴-1 = 16777215. In other words only integer numbers between -16777215 to 16777215 can be exactly represented as a 32 bit float.

Your two values 1586238540 and 1586238600 are outside that range and both get truncated to the same value 1586238592. And it's that truncated value that's being used as key for the map.

if you add this to your code

fmt.Println(t1)
fmt.Println(t2)

you'll see 1.5862386e+09 as result for both because the value is too big for a float32. with float64 you'll see the proper value printed

1.58623854e+09
1.5862386e+09

for more info wikipedia

Related