想知道是否有人可以帮助我。也许源代码中潜藏着一些东西,不幸的是我对 C 的了解还不够,无法捕捉到造成这种情况的原因:
我运行以下 awk 脚本作为测试工具来说明此行为:
#! /usr/bin/env -S awk -E
BEGIN {
OFMT = "%2.3e"
CONVFMT = "%2.3e"
print "gawk version:", PROCINFO["version"]
}
{
for (f=1; f<=NF; f++) {
print ""
print "No modification:", typeof($f), $f
print "Casting strnum to number via OFMT (" OFMT ") with 0+$" f ":",
typeof(0+$f), 0+$f
print "Casting strnum to string via CONVFMT (" CONVFMT ") with \"\" 0+$" f ":",
typeof("" 0+$f), "" 0+$f
print "Using strtonum():", strtonum($f)
printf "Explicitly formatting as %%2.3e using printf: %2.3e\n", $f
}
print ""
# "Born" a number (i.e., no conversion from strnum)
x = 32553225
print typeof(x), x
# Now give it a fractional part
x += 0.1
print typeof(x), x
}
$ ./ofmt_test.awk <<< '236437734634 236437734634.000 236437734634.001'
gawk version: 4.2.1
No modification: strnum 236437734634
Casting strnum to number via OFMT (%2.3e) with 0+$1: number 236437734634
Casting strnum to string via CONVFMT (%2.3e) with "" 0+$1: string 236437734634
Using strtonum(): 236437734634
Explicitly formatting as %2.3e using printf: 2.364e+11
No modification: strnum 236437734634.000
Casting strnum to number via OFMT (%2.3e) with 0+$2: number 236437734634
Casting strnum to string via CONVFMT (%2.3e) with "" 0+$2: string 236437734634
Using strtonum(): 236437734634
Explicitly formatting as %2.3e using printf: 2.364e+11
No modification: strnum 236437734634.001
Casting strnum to number via OFMT (%2.3e) with 0+$3: number 2.364e+11
Casting strnum to string via CONVFMT (%2.3e) with "" 0+$3: string 2.364e+11
Using strtonum(): 2.364e+11
Explicitly formatting as %2.3e using printf: 2.364e+11
number 32553225
number 3.255e+07
因此OFMT
对第一个大数 ( 236437734634
) 没有影响,但似乎可以在 printf 语句中进行显式转换。所以我添加了.000
小数部分,这没有效果。然后我将其更改为.001
相反,以前不起作用的所有内容OFMT
现在都可以了吗?
我在最后添加了一个“独立”测试用例,以排除类型转换的strnum
原因。但同样的效果也会发生。
这里OFMT
需要小数点后的非零小数部分,但显式格式转换不需要%e
?
答案1
我看到这个CONVFMT
关于POSIX 扩展描述:
完全等于整数值的数值(请参见 源自 ISO C 标准的概念) 应通过等效于调用将其转换为字符串冲刺函数函数(参见 字符串函数) 与字符串
"%d"
作为FMMT参数和被转换为第一个且唯一的数值表达式 争论。任何其他数值应通过等效于调用来转换为字符串冲刺函数函数与变量的值卷积FMT作为FMMT参数和被转换为第一个且唯一的数值表达式争论。
这几乎描述了您在这里以及在有关部分中看到的内容输出语句:
所有表达式参数均应视为字符串,必要时进行转换;此转换应如中所述awk 中的表达式,例外的是打印函数格式为正交频域调制 应使用而不是值卷积FMT。
因此,我们有它。