这是strconv.ParseFloat()行为预期还是错误?我怎样才能解决它?
问题描述:
运行这段代码,看看我的意思是:Go Playground demo of issue这是strconv.ParseFloat()行为预期还是错误?我怎样才能解决它?
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变量来表示。
但是,当它被解析为float64与strconv.ParseFloat()
并打印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
其实都是相同的值,这样下去是没有错的打印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
更具可读性。
明确。还有几行代码有助于确认:[link](https://play.golang.org/p/j-a-wSXIGt) – Koala3