为了账号安全,请及时绑定邮箱和手机立即绑定

为什么从 float64 到 int 的转换会导致值增加 1?

为什么从 float64 到 int 的转换会导致值增加 1?

Go
泛舟湖上清波郎朗 2022-09-12 17:02:05
将 float64 类型转换为 int 时,我希望结果为 。但是,实际结果是 ,它比 1 大。630948893921274879630948893921274879630948893921274880这是什么原因呢?import (    "fmt")func main() {    var p float64 = 630948893921274879    fmt.Println(int(p))   // 630948893921274880    fmt.Printf("%f\n", p) // 630948893921274880.000000}https://play.golang.org/p/gbXKCkZ6_rF
查看完整描述

3 回答

?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

630948893921274879大于最大整数可以在不进行舍入的情况下进行编码。“浮点数”(即浮点数)的工作方式与科学记数法相同。它们存储一定数量的有效数字,然后将其乘以某个二次方。630948893921274879需要比 float64 可以容纳的更多有效数字,因此它会四舍五入到它可以表示的最接近的值。float64

如果需要处理这么大的整数,则需要始终使用整数。不能转换为浮点值。


查看完整回答
反对 回复 2022-09-12
?
catspeake

TA贡献1111条经验 获得超0个赞

float64不会比“免费”“更大”。它牺牲了精度和范围。int64

在一定幅度之后,整数只能表示为最接近的 2。当你变得更大时,你最终会每4个跳过一次,然后每8个跳过一次,依此类推。


查看完整回答
反对 回复 2022-09-12
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

您的浮点数不能存储为630948893921274879,而是最接近的模拟630948893921274880。以基数 2 为准,lg(630948893921274879) 介于 59 和 60 之间。因此,数字之间的间距为 2^(59-52) = 2^7 = 128。这意味着 2^59 和 2^60 之间的任何数字都将四舍五入到最接近的 128 的倍数。

解释:浮点数(任何大小,不仅仅是64)不是一个数字,而是3个数字相乘。对于 64 位浮点数:第一个数字是符号,长度为 1 位。第二个数字是指数,长度为 11 位。最后一个数字是有效数(AKA 尾数、分数和其他一些名称),长度为 52 位。最后一个数字是 -1^符号 * 2^指数 * 1.有效数。1.有效数将等于 1 和(几乎)2 之间的数字。这意味着,每次达到2的倍数时,指数将增加,有效数将重置。由于指数增加,您获得的数字的准确性将降低一半,因为有效数的最微小的增加现在将是两倍大。您的数字恰好位于有效数的最小变化导致增加128的点;因此,您的数字将四舍五入到最接近的 128 的倍数。因此,导致问题的不是 float64 到 int 的转换,而是 float64 本身。


查看完整回答
反对 回复 2022-09-12
  • 3 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信