当我检查了 float64 的行为时,我发现了以下行为。
100000
。1e+06
。package main
import "fmt"
func main() {
var a float64 = 100000
fmt.Println(a) // output: 100000
var b float64 = 1000000
fmt.Println(b) // output: 1e+06 (expected: 1000000)
}
有人可以帮我解释为什么输出会根据位数而不同吗?
您正在观察由于 Go 的默认浮点数格式导致的行为。当打印
float64
时,Go 尝试简洁地表示数字。它打印较小数字的完整值(如 100000
)。然而,一旦数字有更多位数(如 1000000
),Go 就会切换到科学记数法(1e+06
)。
如果要确保打印完整值而不使用科学记数法,可以将
fmt.Printf
与格式指令一起使用:
package main
import "fmt"
func main() {
var a float64 = 100000
fmt.Printf("%.f\n", a)
var b float64 = 1000000
fmt.Printf("%.f\n", b)
}
这将打印两个没有科学记数法的数字:
100000
1000000
截至 2024 年 8 月 22 日,在 go.dev/src/strconv/ftoa.go 中做出此科学记数法决策的相关函数:
func formatDigits(dst []byte, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) []byte {
switch fmt {
case 'e', 'E':
return fmtE(dst, neg, digs, prec, fmt)
case 'f':
return fmtF(dst, neg, digs, prec)
case 'g', 'G':
// trailing fractional zeros in 'e' form will be trimmed.
eprec := prec
if eprec > digs.nd && digs.nd >= digs.dp {
eprec = digs.nd
}
// %e is used if the exponent from the conversion
// is less than -4 or greater than or equal to the precision.
// if precision was the shortest possible, use precision 6 for this decision.
if shortest {
eprec = 6
}
exp := digs.dp - 1
if exp < -4 || exp >= eprec {
if prec > digs.nd {
prec = digs.nd
}
return fmtE(dst, neg, digs, prec-1, fmt+'e'-'g')
}
if prec > digs.dp {
prec = digs.nd
}
return fmtF(dst, neg, digs, max(prec-digs.dp, 0))
}
// unknown format
return append(dst, '%', fmt)
}