这里的问题是常量和浮点数的表示形式。
常数以任意精度表示。浮点数使用IEEE
754标准表示。
规格:常数:
数字常数表示任意精度的值,并且不会溢出。
规格:数值类型:
float64 the set of all IEEE-754 64-bit floating-point numbers
在IEEE 754中,使用64位(
float64在Go中)的 53位
双精度用于存储数字。这意味着可以表示的最大位数(最大位数)是其中的位数
2<<52(1位表示符号):
2<<52 : 9007199254740992Your constant: 6161047830682206209
精确到15.95位数字(16位数字,但不是您可以用16位数字描述的所有值,最多不超过
9007199254740992)。
您尝试放入类型变量的整数常量
float64根本 无法容纳 52位,因此必须四舍五入,并且数字(或位)将被截断(丢失)。
您可以通过打印原始
n float64号码来进行验证:
var n float64 = 6161047830682206209fmt.Printf("%fn", n)fmt.Printf("%dn", uint64(n))输出:
6161047830682206208.0000006161047830682206208
问题不在于转换,问题在于
float64您尝试转换的值已经不等于您尝试为其分配的常数。
出于好奇:
使用更大的数字尝试相同的操作:与第一个const相比,+ 500:
n = 6161047830682206709 // +500 compared to first!fmt.Printf("%fn", n2)fmt.Printf("%dn", uint64(n2))输出 仍然 相同(最后一位/位被截断,包括+500!):
6161047830682206208.0000006161047830682206208
尝试使用一个较小的数字,该数字可以使用52位(小于16位数字)精确表示:
n = 7830682206209fmt.Printf("%fn", n)fmt.Printf("%dn", uint64(n))输出:
7830682206209.0000007830682206209
在Go Playground上尝试一下。



