运行以下代码,了解我的意思:Go Playground demo of issue
package main
import (
"fmt"
"strconv"
)
func main() {
// From https://golang.org/src/math/const.go
var SmallestNonzeroFloat64AsString string = "4.940656458412465441765687928682213723651e-324"
var SmallestNonzeroFloat64 float64
var err error
SmallestNonzeroFloat64, err = strconv.ParseFloat(SmallestNonzeroFloat64AsString, 64)
if err != nil {
panic(err)
}
fmt.Printf("SmallestNonzeroFloat64 = %g\n", SmallestNonzeroFloat64)
fmt.Printf("SmallestNonzeroFloat64 = %s\n", strconv.FormatFloat(SmallestNonzeroFloat64, 'f', -1, 64))
}
SmallestNonzeroFloat64
是在math/const.go中定义的,我假设它可以由float64变量表示。但是,当使用
strconv.ParseFloat()
将其解析为float64并使用strconv.FormatFloat()
打印时,结果将四舍五入。我得到的不是
4.940656458412465441765687928682213723651e-324
,而是5e-324
(或它的非指数等效物,您可以在Go Playground结果中看到)。结果四舍五入。有办法找回
4.940656458412465441765687928682213723651e-324
吗?还是一个错误?
最佳答案
这不是错误。
您可以要求Go打印更多数字。
fmt.Printf("SmallestNonzeroFloat64 = %.40g\n", SmallestNonzeroFloat64)
// 4.940656458412465441765687928682213723651e-324
但是,
5e-324
和4.94…e-324
实际上是相同的值,因此Go打印5e-324
并没有错。此值(2-1074)是Float64表示的最小正数(在其他语言中也称为double
)。较大的数字都是此的倍数,例如下一个最小的数字将是2×2-1074 = 1e-323
,下一个将是3×10-1074 = 1.5e-323
,依此类推。换句话说,比
5e-324
更精确的所有数字都无法在Float64中表示出来。因此,在“5”之后再打印更多数字是没有意义的。而且5e-324
当然比4.94…e-324
更具可读性。关于go - 这是strconv.ParseFloat()行为的预期还是错误?我该如何解决?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42826814/