First, we need to understand the documentation correctly:
width sets the minimum field width, and precision sets the number of places after the decimal number, if necessary, except that for% g /% G it sets the total number of digits.
This line is grammatically correct, but it is really confusing in the last part of this sentence: it actually means precision , not width .
Therefore, consider a few examples:
123.45 12312.2 1.6069 0.6069 0.0006069
and you print it as 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 will happen to the last 2 example? Are you kidding me by no more than 5 digits?
This is a confusing part in print: leading 0s will not be considered digits, and will not be reduced if less than 4 zeros remain .
Look at behavior 0 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 conclusion:
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
Thus, you could see that when the number is less than 4 leading 0, they will be counted and reduced if there are more.
Well, the next thing is width . From the documentation, width indicates only the minimum width,, including decimal place and exponent . This means that if you have more digits than the specified width , it will shoot from the width.
Remember that the width will be taken into account as the last step, which means that it needs to first fulfill the accuracy field .
Let's get back to your business. You specified %10.9g , which means you want the total digit to be 9, excluding the leading 0 and the minimum width of 10 , including decimal place and exponent, and precision should take precedence.
0.0606060606060606 : take 9 digits without a leading 0, will give you 0.0606060606 , since it is already 12 wide, it skips a minimum width of 10;
0.3333333333333333 : take 9 digits without a leading 0, will give you 0.333333333 , since it is already 11 wide, it skips a minimum width of 10;
0.05 : take 9 digits without a leading 0, will give you 0.05 , since it will be less than 10 wide, it will fill 6 more with width to get 10 wide;
0.4 : the same as above;
0.1818181818181818 : take 9 digits without a leading 0, will give you 0.181818182 with rounding , since it is already 11 wide, it skips a minimum width of 10.
So this explains why you got a funny print.