Go 使用相同浮点常量值的不同模式会导致不同的结果

Go 使用相同浮点常量值的不同模式会导致不同的结果,go,floating-point,ieee-754,Go,Floating Point,Ieee 754,在下面的go代码片段中,我很难理解为什么结果不同: func main() { a := -0.2; b := -0.1; fmt.Println(a+b) //Outputs expected float value with rounding error : -0.30000000000000004 c := (-0.2)+(-0.1) fmt.Println(c) //Will ouput -0.3 (the actual exact c

在下面的go代码片段中,我很难理解为什么结果不同:

func main() {
    a := -0.2; b := -0.1; 
    fmt.Println(a+b)
    //Outputs expected float value with rounding error  : -0.30000000000000004
    c := (-0.2)+(-0.1)
    fmt.Println(c)
    //Will ouput -0.3 (the actual exact constant).
}
到底发生了什么,当这些常量不用于实例化浮点时,go是否以某种方式将c操作作为常量而不是浮点64操作执行? 完整工作版本:


如果您有任何见解,我们将不胜感激。

我尝试使用java,结果是

公共类StringTest{
公共静态void main(字符串[]args){
双a=-0.2;
双b=-0.1;
系统输出打印项次(a+b);
//  -0.30000000000000004
双c=a+b;
系统输出打印ln(c);
// -0.30000000000000004
}
}
似乎任何使用二进制浮点数的编程语言都会有这个问题。某些语言的数字类型使用IEEE754标准来表示数字。
您可以看到什么是IEEE-745浮点。

很可能是因为编译器在第二种情况下的编译过程中计算结果。这是一个非常常见的优化。无论如何,舍入误差出现在第二种情况下,而不是第一种情况下。编译器在生成赋值操作之前对结果进行舍入。像
0.1
0.2
0.3
这样的数字在第一部分和第二部分使用浮点数:读取Go如何处理常数:它们(几乎)是任意精度的。另外
fmt.Println()
如果像
fmt.Printf(%.20f',c)
那样打印,则执行一些舍入操作,您将看到
-0.2999999999999998890
的结果。游乐场使用遵循Go语言规范的普通Go编译器。因此,是的,
(-0.2)+(-0.1)
在编译期间计算为-0.3,并且该值被分配给c。一切都是100%按照语言规范完成的。当你说“而不是遵循正常的浮点操作流程”时,你是什么意思。除了语言规范所说的以外,什么是“正常浮点操作”?该规范简短、可读且可搜索:“const”的前三个搜索结果都是目录中的相关条目。围棋确实不同于其他语言。在大多数语言中,你必须咨询专家,在Go中你可以搜索规范,这通常更快。Go计算常量的规则与大多数其他主流编程语言的规则大不相同。Java中发生的事情对于理解OP的Go示例中发生的事情并不是很有用