Weird subtraction result in golang

huangapple go评论81阅读模式
英文:

Weird subtraction result in golang

问题

代码中的问题是由于浮点数精度导致的。在Go语言中,浮点数的精度是有限的,因此在进行浮点数计算时可能会出现舍入误差。在这种情况下,idlebusy的值非常大,相加后的结果超出了浮点数的表示范围,导致舍入误差,最终结果为0.000000。

要解决这个问题,可以考虑使用更高精度的数据类型,如big.Float,或者重新设计计算逻辑以避免精度问题。

英文:

code:

func main() {
	var idle float64 = 1.8483711496702958e+18
	busy := float64(100.0) - idle
	sum := idle + busy
	fmt.Printf("idle: %f\n", idle)
	fmt.Printf("busy: %f\n", busy)
	fmt.Printf("sum: %f\n", sum)
}

result:

idle: 1848371149670295808.000000
busy: -1848371149670295808.000000
sum: 0.000000

I would ask why busy + idle = 0.000?

Go Playground: https://go.dev/play/p/WmtK9AuN_yt

答案1

得分: 2

idle相对于busy要大几个数量级,差异相当于10的16次方倍!这比浮点数的精度还要大,浮点数的精度由IEEE 754标准定义。将100加到-idle上不会改变它的值太多。

如果你减小idle,你会得到你期望的结果:

var idle float64 = 1.8483711496702958e+15

通过这个改变,输出将会是(在Go Playground上试一试):

idle: 1848371149670295.750000
busy: -1848371149670195.750000
sum: 100.000000

浮点数只存储一个数的最重要的位数。如果idle大约是10的18次方,将100加到它上面只会改变那些没有被准确(或根本没有)表示的位数。如果你将idle减小到10的15次方或更低,那么加上100将会改变仍然被表示的位数,你将会看到期望的结果。

英文:

idle compared to busy is several orders of magnitude bigger, the difference is like 10^16 times! That's bigger than the precision of floating point numbers which is defined by IEEE 754 standard. Adding 100 to -idle won't change it "much".

If you decrease idle, you get what you expect:

var idle float64 = 1.8483711496702958e+15

With this change, output will be (try it on the Go Playground):

idle: 1848371149670295.750000
busy: -1848371149670195.750000
sum: 100.000000

Floating point numbers only store the most significant bits of a number. If idle is around 10^18, adding 100 to it would only change bits that are not represented precisely (or at all). If you decrease idle to like 10^15 or lower, then adding 100 will change bits that are still represented, and you'll see the expected result.

huangapple
  • 本文由 发表于 2022年3月17日 15:30:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/71508481.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定