繁体   English   中英

Golang将float64转换为int错误

[英]Golang converting float64 to int error

在将float转换为int时,如何避免浮点错误。 例如,以下代码打印: 0.5499999999999972当我伤口期望它打印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

计算机一般以二进制表示存储数字。 数字100.55不能用有限二进制数表示: 100.55是二进制表示中的无穷数(同样的原因,为什么1/3不能用有限的十进制数表示,它是无穷无尽的序列: 0.333333333.... )。

但Go(与任何其他语言一样)使用IEEE-754标准存储float64类型,这是一种有限二进制表示。 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

你从中减去100float64(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),这是一个整数。 只有当您需要将结果打印为USD时,才能打印出类似的内容

cents := 10055
fmt.Printf("%d.%d $", cents/100, cents%100)

输出:

100.55 $

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM