go - 不能使用特定的 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
更改result
为map[float64]map[float32]float32
and t1
,t2
相应地给出正确的结果。
这种奇怪行为的原因可能是什么?
解决方案
一个 32 位浮点数有一个 23 位尾数,隐含在前的最高 1 位。所以尾数可以表示的最大值是 2²⁴-1 = 16777215。换句话说,只有 -16777215 到 16777215 之间的整数可以精确地表示为 32 位浮点数。
您的两个值 1586238540 和 1586238600 超出了该范围,并且都被截断为相同的值 1586238592。正是该截断值用作地图的键。
推荐阅读
- javascript - 使用 Export Default { myNamedModule } - 然后在 React Native 中导入该命名模块?
- java - 无法将消息对象从 RabbitMQ 转换为 java 类
- gradle - 如何在gradle配置期间防止依赖解析
- javascript - foreach 是否保证每次在相同的数据集上都以相同的顺序循环?
- ruby - 访问 Json 对象导轨
- regex - Hive regexp_extract 返回 NULL
- r - R - 访问列名称的 XML 模式属性名称
- versionone - 当网络出现故障时,如何在 Continuum 中重新运行活动?
- python - 替换列表中的每个元素
- user-interface - 气流显示超过 365 达格伦