Firstly, we need to understand the documentation correctly:
width sets the minimum width of the field and precision sets the number of places after the decimal, if appropriate, except that for %g/%G it sets the total number of digits.
This line is grammatically correct, but the it in the last part of this sentence is really confusing: it actually refers to the precision, not the width.
Therefore, let's look at some examples:
123.45
12312.2
1.6069
0.6069
0.0006069
and you print it like fmt.Printf("%.4g")
, it gives you
123.5
1.231e+04
1.607
0.6069
0.0006069
only 4 digits, excluding all decimal points and exponent. But wait, what happens to the last 2 example? Are you kidding me isn't that more than 5 digits?
This is the confusing part in printing: leading 0s won't be counted as digits, and won't be shrunk when there are less than 4 zeros.
Let's look at 0 behavior using the example below:
package main
import "fmt"
func main() {
fmt.Printf("%.4g\n", 0.12345)
fmt.Printf("%.4g\n", 0.012345)
fmt.Printf("%.4g\n", 0.0012345)
fmt.Printf("%.4g\n", 0.00012345)
fmt.Printf("%.4g\n", 0.000012345)
fmt.Printf("%.4g\n", 0.0000012345)
fmt.Printf("%.4g\n", 0.00000012345)
fmt.Printf("%g\n", 0.12345)
fmt.Printf("%g\n", 0.012345)
fmt.Printf("%g\n", 0.0012345)
fmt.Printf("%g\n", 0.00012345)
fmt.Printf("%g\n", 0.000012345)
fmt.Printf("%g\n", 0.0000012345)
fmt.Printf("%g\n", 0.00000012345)
}
and the output:
0.1235
0.01235
0.001234
0.0001234
1.234e-05
1.234e-06
1.235e-07
0.12345
0.012345
0.0012345
0.00012345
1.2345e-05
1.2345e-06
1.2345e-07
So you could see, when there are less than 4 leading 0s, they will be counted, and be shrunk if there are more than that.
Ok, next thing is the width
. From the documentation, width
only specifies the minimum width, including decimal place and exponent. Which means, if you have more digits than what width
specified, it will shoot out of the width.
Remember, width will be taken account as the last step, which means it needs to first satisfy the precision field.
Let's go back to your case. You specified %10.9g
, that means you want a total digit of 9, excluding the leading 0
, and a min width of 10
including decimal place and exponent, and the precision should take priority.
0.0606060606060606
: take 9 digits without leading 0 will give you 0.0606060606
, since it's already 12 width, it passes the min width of 10;
0.3333333333333333
: take 9 digits without leading 0 will give you 0.333333333
, since it's already 11 width, it passes the min width of 10;
0.05
: take 9 digits without leading 0 will give you 0.05
, since it's less than width 10, it will pad with another 6 width to get width of 10;
0.4
: same as above;
0.1818181818181818
: take 9 digits without leading 0 will give you 0.181818182
with rounding, since it's already 11 width, it passes the min width of 10.
So this explains why you got the funny printing.