Google Go为什么0.1 + 0.2会得到0.3? [英] Why does 0.1 + 0.2 get 0.3 in Google Go?

查看:239
本文介绍了Google Go为什么0.1 + 0.2会得到0.3?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只要使用浮点数,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有不同的值?



Go如何在常量上执行算术?



Golang将float64转换为int错误

编译器的评估不同于常量表达式和其他表达式



为什么要添加0.1多次保持无损?





Go:将float64转换为带有乘数的int

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.

fmt.Println(0.1 + 0.2)
// Output : 0.3

Why is 0.3 coming out instead of 0.30000000000000004 ?

解决方案

It is because when you print it (e.g. with the fmt package), the printing function already rounds to a certain amount of fraction digits.

See this example:

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)

Output (try it on the Go Playground):

0.3
0.29999999999999998890
0.30000000000000004
0.30000000000000004441

First we used constants because that's different than using (non-constant) values of type float64. Numeric constants represent exact values of arbitrary precision and do not overflow.

But when printing the result of 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).

Next we started with variables of type 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.

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?

Golang Round to Nearest 0.05

Go: Converting float64 to int with multiplier

这篇关于Google Go为什么0.1 + 0.2会得到0.3?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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