为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕田峪7331174 2021-08-23 15:31:53
在下面的简单的计算,c并d结束了不同的值(它们是关闭的单个位)。为什么?a := 4000.0b := 1e-9c := a / bd := 4000.0 / 1e-9
查看完整描述

1 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

a被分配了4000.0表示为 a 的次佳值float64,它0x40AF400000000000正好对应于4000.0。


b是 的次佳值1e-9,表示为 a float64,它是0x3E112E0BE826D695并且对应于1.00000000000000006228159145778E-9。你在这里失去了精度。


因此,在计算之前,c您已经有轻微的不精确性。然后当c实际计算时,你会失去一些更精确的四舍五入。


在 的情况下d,只有一个“次优”在进行;当将编译时计算的全精度值表示4000.0 / 1e-9为 a 时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是在运行时根据我描述的两个常量计算的。


查看完整回答
反对 回复 2021-08-23
  • 1 回答
  • 0 关注
  • 161 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信