While I have checked the behavior of float64, I found the following behavior.
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)
}
Could someone please help me why the output differs depending on the number of digits.
You are observing behavior due to Go's default formatting for floating-point numbers. When printing a float64
, Go tries to represent the number concisely. It prints the full value for smaller numbers (like 100000
). However, once the number has more digits (like 1000000
), Go switches to scientific notation (1e+06
).
If you want to ensure the full value is printed without scientific notation, you can use fmt.Printf
with a formatting directive:
package main
import "fmt"
func main() {
var a float64 = 100000
fmt.Printf("%.f\n", a)
var b float64 = 1000000
fmt.Printf("%.f\n", b)
}
This will print both numbers without scientific notation:
100000
1000000
Try on godbolt.org
Relevant function that makes this scientific notation decision in source code at go.dev/src/strconv/ftoa.go as of 2024-08-22:
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)
}