猿问

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

将 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


泛舟湖上清波郎朗
浏览 118回答 3
3回答

至尊宝的传说

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

catspeake

float64不会比“免费”“更大”。它牺牲了精度和范围。int64在一定幅度之后,整数只能表示为最接近的 2。当你变得更大时,你最终会每4个跳过一次,然后每8个跳过一次,依此类推。

拉风的咖菲猫

您的浮点数不能存储为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 本身。
随时随地看视频慕课网APP

相关分类

Go
我要回答