首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么gawk (有时?)想想2.0e-318 > 2.0?

为什么gawk (有时?)想想2.0e-318 > 2.0?
EN

Unix & Linux用户
提问于 2020-01-27 15:54:10
回答 2查看 94关注 0票数 3

我试图使用gawk找到一列数据的最大值:

代码语言:javascript
复制
gawk 'BEGIN{max=0} {if($1>0+max) max=$1} END {print max}' dataset.dat

其中dataset.dat看起来是这样的:

2.0e-318

命令的输出是

2.0e-318

明显小于2。

我的错误在哪里?

编辑

有趣的是,如果您交换输入文件的行,则输出将变为

2.0

编辑2

我的gawk版本是GNU Awk 4.2.1,API: 2.0 (GNU MPFR 4.0.2,GNU MP 6.1.2)。

EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2020-01-27 16:09:20

0+需要以每个$1作为前缀,以强制进行数字转换。max不需要0+ --它存储时已经转换为数字。

代码语言:javascript
复制
Paul--) AWK='
> BEGIN { max = 0; }
> 0+$1 > max { max = 0 + $1; }
> END { print max; }
> '
Paul--) awk "${AWK}" <<[][]
> 2.0
> 2.0e-318
> [][]
2
Paul--) awk "${AWK}" <<[][]
> 2.0e-318
> 2.0
> [][]
2
票数 2
EN

Unix & Linux用户

发布于 2020-01-27 21:39:48

在awk中处理这么小的数字(2e-318)有几个问题。

  • 首先,需要将输入转换为一个数字,然后再使用它。这通常是通过添加0来完成的。所以,你需要这样的东西: val=0+$1
  • 第二,标准双精度浮点数(53位尾数和11位指数) 指数的11位宽度允许表示介于10e-308和10e308之间的数字.,所以法线浮点数不能表示这样的数字。$ echo‘1e-3071e-308’区awk '{print $1,$1+0,$2,$2+0}‘1e-307 1e-307 1e-308 0默认GNU awk不会接受(正常)低于1e-308的值。
  • 第三,awk ( CNVFMT和OFMT)的默认转换格式设置为"%.6g"。超过6个重要数字的数字将被截断。想要更多有意义的数字,就去问他们。就像15位的%.15g (不要要求超过17位的53位尾数,它可能会说谎)。
  • 第四,最好将max的第一个值设置为第一个输入。如果输入有负最大值,则将最大值设置为0将失败。

如果您使用的是GNU awk,并且它是以任意精度编译的,您可以使用:

代码语言:javascript
复制
$ printf '%s\n' 2e-318 2e-317 2e-307 2e-308 2e-319 | 
    awk -M -v PREC=100     'BEGIN{OFMT="%.15g"};
        {val=0+$1};
        NR==1{max=val};
        {print($1,val,max)};
        val>max{max=val}
        END{print max}'

2e-318 2e-318 2e-318
2e-317 2e-317 2e-318
2e-307 2e-307 2e-317
2e-308 2e-308 2e-307
2e-319 2e-319 2e-307
2e-307 

或者简化为用例:

代码语言:javascript
复制
awk -M -v PREC=100 '
    BEGIN{OFMT="%.15g"};    # allow more than 6 figures
    {val=0+$1};             # convert input to a (float) number.
    NR==1{max=val};         # On the first line, set the max value.
    val>max{max=val}        # On every entry keep track of the max.
    END{print max}          # At the end, print the max.
    '  file                 # file with input (one per line).
票数 4
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/564397

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档