Google Go为什么0.1 + 0.2会得到0.3? [英] Why does 0.1 + 0.2 get 0.3 in Google Go?
问题描述
只要使用浮点数,0.1就不能在内存中完全表示,所以我们知道这个值通常会出现在0.10000000000000004之间。
但是当使用去添加0.1和0.2。
我得到0.3。
fmt.Println(0.1 + 0.2)
//输出: 0.3
为什么0.3出来而不是0.30000000000000004?
这是因为当你打印它时(例如使用 fmt
包),打印功能已经舍入到一定数量的小数位。
请参阅这个例子:
const ca,cb = 0.1,0.2
fmt.Println(ca + cb)
fmt.Printf(%。20f \ n,ca + cb)
var a,b float64 = 0.1,0.2
fmt.Println(a + b)
fmt.Printf(%。20f \\\
,a + b)
输出它在 Go Playground 上):
0.3
0.29999999999999998890
0.30000000000000004
0.30000000000000004441
<首先,我们使用了常量,因为这与使用类型<非常量> code> float64 。 ,常量值必须转换为非常量的类型值才能传递给 fmt.Println()
。该值将是 float64
类型,它不能完全表示 0.3
。但 fmt.Println()
会将其舍入为〜16个小数位数,这将是 0.3
。但是,当我们明确声明我们希望它显示20位数字时,我们会看到它不是确切的。请注意,只有 0.3
会被转换为 float64
,因为常数运算 0.1 + 0.2
将由编译器评估(编译时)。
接下来我们开始使用 float64
,毫不奇怪,输出结果并不是 0.3
,但是这次即使使用默认舍入,我们得到的结果也不同于 0.3
。这是因为在第一种情况下(常量)它被转换为 0.3
,但这次都是 0.1
和 0.2
被转换为 float64
,其中没有一个是确切的,并且添加它们会产生一个距离更大的数字从 0.3
,足够大,可以对 fmt
包的默认舍入做出视觉外观。
查看类似/相关问题+答案以了解有关该主题的更多信息: a href =https://stackoverflow.com/questions/27819137/why-do-these-two-float64s-have-different-values/27819409#27819409>为什么这两个float64s有不同的值?
As long as floating point is used, 0.1 can not be represented exactly in memory, so we know that this value usually comes out to 0.10000000000000004. But when using go to add 0.1 and 0.2.
I'm getting 0.3. Why is 0.3 coming out instead of 0.30000000000000004 ? It is because when you print it (e.g. with the See this example: Output (try it on the Go Playground): First we used constants because that's different than using (non-constant) values of type But when printing the result of Next we started with variables of type Check out similar / relevant questions+answers to know more about the topic: Why do these two float64s have different values? How does Go perform arithmetic on constants? Golang converting float64 to int error Does go compiler's evaluation differ for constant expression and other expression Why does adding 0.1 multiple times remain lossless? Go: Converting float64 to int with multiplier 这篇关于Google Go为什么0.1 + 0.2会得到0.3?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
fmt.Println(0.1 + 0.2)
// Output : 0.3
fmt
package), the printing function already rounds to a certain amount of fraction digits.const ca, cb = 0.1, 0.2
fmt.Println(ca + cb)
fmt.Printf("%.20f\n", ca+cb)
var a, b float64 = 0.1, 0.2
fmt.Println(a + b)
fmt.Printf("%.20f\n", a+b)
0.3
0.29999999999999998890
0.30000000000000004
0.30000000000000004441
float64
. Numeric constants represent exact values of arbitrary precision and do not overflow.ca+cb
, the constant value have to be converted to a non-constant, typed value to be able to be passed to fmt.Println()
. This value will be of type float64
, which cannot represent 0.3
exactly. But fmt.Println()
will round it to like ~16 fraction digits, which will be 0.3
. But when we explicitly state we want it displayed with 20 digits, we'll see it's not exact. Note that only 0.3
will be converted to float64
, because the constant arithmetic 0.1+0.2
will be evaluated by the compiler (at compile time).float64
, and to no surprise, output wasn't 0.3
exactly, but this time even with the default rounding we got a result different from 0.3
. The reason for this is because in the first case (constants) it was 0.3
that was converted, but this time both 0.1
and 0.2
were converted to float64
, none of which is exact, and adding them resulted in a number having bigger distance from 0.3
, big enough to make a "visual appearance" with the default rounding of the fmt
package.