首页 > 解决方案 > 不能使用特定的 float32 值作为映射键

问题描述

使用 float32 作为映射键返回意外结果

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 go1.14 linux/amd64

更改resultmap[float64]map[float32]float32and t1t2相应地给出正确的结果。

这种奇怪行为的原因可能是什么?

标签: gofloating-point

解决方案


一个 32 位浮点数有一个 23 位尾数,隐含在前的最高 1 位。所以尾数可以表示的最大值是 2²⁴-1 = 16777215。换句话说,只有 -16777215 到 16777215 之间的整数可以精确地表示为 32 位浮点数。

您的两个值 1586238540 和 1586238600 超出了该范围,并且都被截断为相同的值 1586238592。正是该截断值用作地图的键。


推荐阅读