我试图得到一些使用相同宽度格式化的浮点数fmt.Printf().
例如,给定浮点值0.0606060606060606,0.3333333333333333,0.05,0.4和0.1818181818181818,我想将每个值格式化为10符文:
0.06060606
0.33333333
0.05
0.4
0.18181818
Run Code Online (Sandbox Code Playgroud)
但我无法理解它是如何完成的.文档说
对于浮点值,width设置字段的最小宽度,precision设置小数点后的位数(如果适用),但%g /%G除外,它设置总位数.例如,给定123.45格式%6.2f打印123.45而%.4g打印123.5.%e和%f的默认精度为6; 对于%g,它是唯一标识值所需的最小位数.
因此,如果我使用%f较大的数字将不适合10个字符的约束,因此%g是必需的.要获得最小宽度为10 %10g并获得最大数量的9位数(点的+1)%.9g,但将它们组合起来%10.9g并不像我期望的那样
0.0606060606
0.333333333
0.05
0.4
0.181818182
Run Code Online (Sandbox Code Playgroud)
为什么我得到10符文的字符串,其他的符文是11符文,其他符号是12符文?
特别是,似乎%.9g总共不产生9位数.参见例如:http://play.golang.org/p/ie9k8bYC7r
首先,我们需要正确理解文档:
宽度设置字段的最小宽度,精度设置小数点后的位数(如果适用),但 %g/%G 除外,它设置总位数。
这行在语法上是正确的,但是这句话最后部分的it确实令人困惑:它实际上指的是precision,而不是width。
因此,让我们看一些例子:
123.45
12312.2
1.6069
0.6069
0.0006069
Run Code Online (Sandbox Code Playgroud)
你打印它就像fmt.Printf("%.4g"),它给了你
123.5
1.231e+04
1.607
0.6069
0.0006069
Run Code Online (Sandbox Code Playgroud)
仅 4 位数字,不包括所有小数点和指数。但是等等,最后两个例子会发生什么?你开玩笑吧,这不是超过5位数吗?
这是打印中令人困惑的部分:前导 0不会被计为数字,并且当 0 少于 4 个时不会被缩小。
让我们使用下面的示例来看看 0 行为:
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)
}
Run Code Online (Sandbox Code Playgroud)
和输出:
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
Run Code Online (Sandbox Code Playgroud)
所以你可以看到,当前导 0 少于 4 个时,它们将被计数,如果超过 4 个,则会被缩小。
好吧,接下来的事情就是width. 从文档中,width仅指定最小宽度,包括小数位和指数。这意味着,如果您的数字多于width指定的数字,它将超出宽度。
请记住,宽度将被视为最后一步,这意味着它需要首先满足精度字段。
让我们回到你的案例。您指定了%10.9g,这意味着您想要的总数字为 9,不包括前导0,最小宽度为10包括小数位和指数,并且精度应优先。
0.0606060606060606:取9位不带前导0的数字给你0.0606060606,因为它已经是 12 宽度,它超过了最小宽度 10;
0.3333333333333333:取9位不带前导0的数字给你0.333333333,因为它已经是 11 宽度,它超过了最小宽度 10;
0.05:取9位不带前导0的数字给你0.05,因为它小于宽度 10,所以它将用另外 6 个宽度填充以获得宽度 10;
0.4:同上;
0.1818181818181818:取 9 位数字而不带前导0 会给你0.181818182四舍五入,因为它已经是 11 宽度,它超过了最小宽度 10。
这解释了为什么你会得到有趣的印刷。