2017-03-16 52 views
1

运行这段代码,看看我的意思是: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)) 
} 

SmallestNonzeroFloat64math/const.go定义,我以为它可以通过一个float64变量来表示。

但是,当它被解析为float64与strconv.ParseFloat()并打印strconv.FormatFloat()结果是舍入。

而不是4.940656458412465441765687928682213723651e-324我得到5e-324(或它的非指数等价物,你可以在Go Playground结果中看到)。结果是四舍五入的。

有没有办法找回4.940656458412465441765687928682213723651e-324

或者它是一个错误?

回答

7

这不是一个错误。

你可以问Go打印更多数字。

fmt.Printf("SmallestNonzeroFloat64 = %.40g\n", SmallestNonzeroFloat64) 
// 4.940656458412465441765687928682213723651e-324 

然而,5e-3244.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更具可读性。

+0

明确。还有几行代码有助于确认:[link](https://play.golang.org/p/j-a-wSXIGt) – Koala3

相关问题