awk中的数学-浮点数的意外格式-精度损失

awk中的数学-浮点数的意外格式-精度损失,awk,Awk,我正在用awk做一些简单的数学题 user@lab-client:~$ awk '{ram=(1.8 * 1024) * 1024; print ram}' 1.88744e+06 所以我假设这意味着这个数字太大,无法存储在变量“ram”中 总数为:1887436.8 让我们尝试将该数字存储在变量中 user@lab-client:~$ awk '{ram=1887436.8; print ram}' 1.88744e+06 还是一样。但是如果我们去掉了“.”呢 进一步的测试表明,当点位

我正在用awk做一些简单的数学题

user@lab-client:~$ awk '{ram=(1.8 * 1024) * 1024; print ram}'

1.88744e+06
所以我假设这意味着这个数字太大,无法存储在变量“ram”中

总数为:1887436.8

让我们尝试将该数字存储在变量中

user@lab-client:~$ awk '{ram=1887436.8; print ram}'

1.88744e+06
还是一样。但是如果我们去掉了“.”呢

进一步的测试表明,当点位于数字中时,其长度不能超过6位

user@lab-client:~$ awk '{ram=188743.68; print ram}'

188744

所以这不是一个太大的数字,是点把事情搞砸了。如何解决这个问题?

您可以使用printf控制小数点的数量,尽管由于采用浮点表示法,这些数字最终不会很重要

比如说

awk 'BEGIN{for(i=5;i<20;i++) printf "%."i"f\n", 1./3}'

0.33333
0.333333
0.3333333
0.33333333
0.333333333
0.3333333333
0.33333333333
0.333333333333
0.3333333333333
0.33333333333333
0.333333333333333
0.3333333333333333
0.33333333333333331
0.333333333333333315
0.3333333333333333148
awk'BEGIN{for(i=5;i补充:

除了使用
printf
sprintf
显式设置数字格式外,您还可以通过内置变量
OFMT
更改
awk
的默认浮点数格式 请注意,它不适用于整数

OFMT
默认值为
%.6g
,这意味着任何浮点数都四舍五入为6位有效数字,以7开头的指数用科学记数法表示

因此,计算结果
1887436.8
(有8个有效数字)表示为
1.88744e+06
,即用6个有效数字的科学符号表示

以下示例将
OFMT
设置为
%1.f
,以便在默认情况下输出所有小数点后1位的浮点数:

$ awk -v OFMT='%.1f' 'BEGIN {ram=(1.8 * 1024) * 1024; print ram}'
1887436.8
但是,请注意,OFMT的
不适用于以下情况:

  • 如果在字符串串联中使用浮点数:

  • 如果文字可以解析为整数-即使它看起来像一个浮点数:

    $ awk -v OFMT='%.1f' 'BEGIN { print 1.000 }'
    1
    

注意:
awk
中的数字转换和格式有很多微妙之处,尤其是因为浮点数字的精度有限(在
awk
中,浮点数字总是ISO C双精度类型)。

谢谢!原来我的问题确实是这个问题的重复。
$ awk -v OFMT='%.1f' 'BEGIN { print "result: " 1 / 3 }'
result: 0.333333

# Workaround: Use `sprintf()` with OFMT
awk -v OFMT='%.1f' 'BEGIN { print "result: " sprintf(OFMT, 1 / 3) }'
result: 0.3
$ awk -v OFMT='%.1f' 'BEGIN { print 1.000 }'
1