英文:
Weird subtraction result in golang
问题
代码中的问题是由于浮点数精度导致的。在Go语言中,浮点数的精度是有限的,因此在进行浮点数计算时可能会出现舍入误差。在这种情况下,idle
和busy
的值非常大,相加后的结果超出了浮点数的表示范围,导致舍入误差,最终结果为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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论