在 Go 中是否有安全的方法可以将 float64 转换为 int64?

Is there a safe way to cast float64 to int64 in Go?

提问人:Pavlo Maistrenko 提问时间:1/28/2023 更新时间:1/28/2023 访问量:661

问:

我知道 Go 提供的 or typecast 函数。 有没有一种安全的方法可以转换为(截断),因为最大的可表示 64 位浮点数远大于?一种触发溢出错误的方法?int()int64()float64int64math.MaxFloat64math.MaxInt64

GO CASTING 截断

评论

0赞 icza 1/28/2023
您可以在转换前检查该值是小于还是大于。如果是这样,转换肯定会溢出。float64MinInt64MaxInt64
0赞 icza 1/28/2023
@JimB,您可以与最接近 的值进行比较。float64MaxInt64
0赞 JimB 1/28/2023
@icza:是的,我只是想说它可能会令人惊讶,因为它不在+/-1<<53
0赞 Pavlo Maistrenko 1/28/2023
谢谢!这次对话提供了很多见解,吉姆的回答非常翔实。

答:

2赞 JimB 1/28/2023 #1

如果要 a 转换为 (不是强制转换或类型转换),则可以将浮点值与最接近的双精度整数值 和 进行比较。这些数字不能完全存储在一个值中,但它们将存储为高于或低于这些值的下一个整数值:float64int64math.MaxInt64math.MinInt64float64

float64(math.MaxInt64) // 9223372036854775808
float64(math.MinInt64) // -9223372036854775808

因此,只要您的值介于这两个值之间,您就知道它可以转换为无溢出。float64int64

但请注意,如果向另一个方向转换,则无法保证 a 可以准确地表示 ,因为双精度浮点值仅包含 52 位精度。在这种情况下,必须检查该值是否介于 和 之间。float64int64MaxInt64int64-1<<531<<53

无论哪种情况,您都可以使用 math/big 包处理更大的值。