在将浮点数转换为int's时,如何避免浮点错误。例如,下面的代码打印:当我缠绕时,0.5499999999999972
期望它打印0.55
。
package main
import "fmt"
func main() {
x := 100.55
fmt.Println(x - float64(int(x)))
}
Output:
0.5499999999999972
发布于 2016-03-17 08:30:30
您需要了解:100.55
是一个十进制数(以十进制基数表示)。十进制中的100.55
是一个有限的数,正好是:100.55
。
计算机一般以二进制表示形式存储数字。数字100.55
不能用有限二进制数表示:100.55
是二进制表示中的无限个数(与1/3
不能用有限十进制数表示的原因相同,它是一个无穷无尽的序列:0.333333333....
)。
但是Go (和任何其他语言一样)使用float64
标准存储IEEE-754类型,这是一个有限的二进制表示。float64
值使用存储器中的64位来描述数字,其中53位用于描述数字,11位用于指数。
现在当你“说”这个:
x := 100.55
它是一个短变量声明,它将创建一个名为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
的数字。
从其中减去100
(float64(int(x))
就是100.0
):
x = x - float64(int(x))
fmt.Printf("%.50f\n", x)
0.54999999999999715782905695959925651550292968750000
看你怎么办?没什么真正的。您所期望的结果(0.55
)也是二进制表示中的一个无穷多,所以您不能在一个类型为float64
的变量中有确切的0.55
数。
你能做的是像往常一样处理这个数字,但是当你打印它时,把它四舍五入到你选择的小数位。最简单的方法是使用fmt.Printf()
,并使用谓词%f
指定格式字符串,包括精度:
fmt.Printf("%.2f\n", x)
结果:
0.55
另一种选择是避免使用浮点数。例如,如果您要表示美元金额,您可以用100
“乘以”所有的值,并将金额表示为美分(1美元*100),这是一个整数。只有当您需要以美元形式打印结果时,才可以打印以下内容
cents := 10055
fmt.Printf("%d.%d $", cents/100, cents%100)
输出:
100.55 $
https://stackoverflow.com/questions/36052922
复制相似问题