为什么这两个float64有不同的值? [英] Why do these two float64s have different values?

查看:199
本文介绍了为什么这两个float64有不同的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



  fmt.Println(912 * 0.01)
fmt.Println(float64( 912)* 0.01)

https://stackoverflow.com/questions/21895756/why-are-floating-point-numbers-inaccurate\">我明白为什么会发生



但是,为什么第一行打印9.12,最后没有... 01? Go是否将两个无类型常量相乘,并在编译时用9.12字面值替换它们?

spec :


常量表达式总是精确计算;中间值和常量本身的精度可能要比语言中任何预先声明的类型所支持的精度要大得多。


  912 * 0.01 

是一个常量表达式,它被精确地评估。因此,写 fmt.Println(912 * 0.01)与写 fmt.Println(9.12)的效果相同。当你将 912 固定为 float64 时,浮点乘法的另一个操作数被隐式固定为 float64 。因此,表达式 float64(912)* 0.01 表现得像 float64(912)* float64(0.01)。 0.01在 float64 中不能精确表示,因此在表达式 float64(912 * 0.01),它出现在第一个例子中 fmt.Println()的参数中,解释了不同的结果。


Consider these two cases:

fmt.Println(912 * 0.01)
fmt.Println(float64(912) * 0.01)

(Go Playground link)

The second one prints 9.120000000000001, which is actually fine, I understand why that is happening.

However, why does the first line print 9.12, without the …01 at the end? Does Go multiply the two untyped constants and simply replace them with a 9.12 literal when compiling?

解决方案

As per spec:

Constant expressions are always evaluated exactly; intermediate values and the constants themselves may require precision significantly larger than supported by any predeclared type in the language.

Since

912 * 0.01

is a constant expression, it is evaluated exactly. Thus, writing fmt.Println(912 * 0.01) has the same effect as writing fmt.Println(9.12). When you pin 912 to float64, the other operand of the floating-point multiplication is implicitly pinned to float64, too. Thus, the expression float64(912) * 0.01 behaves like float64(912) * float64(0.01). 0.01 is not exactly representable in a float64, thus precision is lost in a different place than in the expression float64(912 * 0.01) which arises in the argument of fmt.Println() in your first example, explaining the different results.

这篇关于为什么这两个float64有不同的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆