为什么浮点文字和变量在Go中给出不同的结果?

时间:2014-10-08 12:18:38

标签: go

在下面的简单计算中,cd最终会得到不同的值(它们会被一个比特关闭)。那是为什么?

a := 4000.0
b := 1e-9
c := a / b
d := 4000.0 / 1e-9

1 个答案:

答案 0 :(得分:6)

a被指定为4000.0的次最佳值,表示为float64,其为0x40AF400000000000且与4000.0完全对应。

b1e-9的下一个最佳值,表示为float640x3E112E0BE826D695且对应1.00000000000000006228159145778E-9。你在这里失去了精确度。

所以在计算c之前你已经有了一点点不精确。然后,当实际计算c时,你会失去一些更精确的舍入。

d的情况下,只有一个“次佳”正在进行中;将编译时计算的4000.0 / 1e-9的全精度值表示为float64

除了变量之外:在C(并且可能是C ++)中,默认是假设变量是非易失性的,即不共享,因此优化通常深入地遵循常量表达式,用计算值替换所有变量。 Go不对变量的范围做出任何假设,因此无法保证替换常量表达式。这可能会在将来发生变化,但是今天在该部门中没有做太多的事情,因此很有可能c实际上是在运行时计算的,而不是在编译时计算的,因为有人习惯于C。


编辑:我参加了@topskip提供的程序:

package main

import "fmt"

func main() {
    a := 4000.0
    b := 1e-9
    c := a / b
    d := 4000.0 / 1e-9
    fmt.Println(a)
    fmt.Println(b)
    fmt.Println(c)
    fmt.Println(d)
}

这是由go tool 6g -S

生成的程序集的一部分
0x0021 00033 (meh.go:6) MOVSD   $f64.40af400000000000+0(SB),X2
0x002a 00042 (meh.go:7) MOVSD   $f64.3e112e0be826d695+0(SB),X3
0x0033 00051 (meh.go:8) MOVAPD  X2,X0
0x0037 00055 (meh.go:8) MOVSD   X3,"".b+64(SP)
0x003d 00061 (meh.go:8) DIVSD   X3,X0

正如你所看到的; c是在运行时根据我描述的两个常量计算的。