Golang将float64转换为int错误
如何在将浮点转换为int时避免浮点错误。 例如,以下代码打印:Golang将float64转换为int错误,go,floating-point,precision,Go,Floating Point,Precision,如何在将浮点转换为int时避免浮点错误。 例如,以下代码打印:0.54999999972当我希望它打印0.55时 package main import "fmt" func main() { x := 100.55 fmt.Println(x - float64(int(x))) } Output: 0.5499999999999972 你需要了解一些事情:100.55是一个十进制数(以十进制基数表示)100.55是一个有限数,正是这样:100.55 packa
0.54999999972
当我希望它打印0.55
时
package main
import "fmt"
func main() {
x := 100.55
fmt.Println(x - float64(int(x)))
}
Output:
0.5499999999999972
你需要了解一些事情:
100.55
是一个十进制数(以十进制基数表示)<十进制中的code>100.55是一个有限数,正是这样:100.55
package main
import "fmt"
func main() {
x := 100.55
fmt.Println(x - float64(int(x)))
}
Output:
0.5499999999999972
一般来说,计算机以二进制形式存储数字。数字100.55
不能用有限的二进制数表示:100.55
是二进制表示法中的无限数(这与1/3
不能用有限的十进制数表示的原因相同,它是一个无休止的序列:0.333..
)
但是Go(和其他任何语言一样)使用标准存储float64
类型,这是一种有限二进制表示。float64
值使用内存中的64位来描述数字,其中53位用于描述数字,11位用于表示指数
现在当你“说”这个:
它是一个将创建一个名为x
的新变量,并从右侧表达式(一个浮点文本)推断其类型的变量,因此按照Go规范x
的类型将是float64
。浮点文字必须进行“转换”,以便使用64位表示(根据IEEE-754规定的规则)。由于100.55
需要无限位以二进制基数精确表示,因此仅使用64位(数字为53位),结果不会(不能)精确地100.55
(而是最接近它的IEEE-754格式的64位二进制数),即:
x := 100.55
fmt.Printf("%.50f\n", x)
100.54999999999999715782905695959925651550292968750000
因此,您开始时的数字不是100.55
package main
import "fmt"
func main() {
x := 100.55
fmt.Println(x - float64(int(x)))
}
Output:
0.5499999999999972
从中减去100
(float64(int(x))
将正好是100.0
):
你能做些什么?没什么。您所期望的结果(0.55
)在二进制表示中也是一个无穷大的数字,因此在类型为float64
的变量中不能有确切的0.55
你能做的就是像平常一样处理这个数字,但是当你打印它时,把它四舍五入到你选择的小数位。最简单的方法是使用动词%f
指定格式字符串,包括精度:
fmt.Printf("%.2f\n", x)
结果:
0.55
另一个选择是避免使用浮点数。例如,如果您要表示美元金额,您可以将所有值乘以100
,并将金额表示为美分(1$*100),这是一个整数。只有当您需要将结果打印为美元时,才可以打印如下内容
cents := 10055
fmt.Printf("%d.%d $", cents/100, cents%100)
输出:
100.55 $
在Python或Ruby REPL中尝试
100.55-100
。在这两种情况下,我都得到了0.54999999972
。你熟悉浮点运算中的gotchas吗?嗨,我不是100%了解如何避免浮点错误。有什么建议吗?你熟悉浮点运算中的gotchas吗?可能是