浮点比较的问题

时间:2011-08-28 19:27:28

标签: bash floating-point comparison numbers

我正在尝试检查从文本文件中读取的值是否为零:

[[ $(echo $line | cut -d" " -f5) -gt 0 ]] && [[ $(echo $line | cut -d" " -f7 | bc -l) -eq 0 ]]

第一个条件没有问题,因为f5是整数。问题来自第二个条件。我收到此错误消息:

[[: 1.235: syntax error: invalid arithmetic operator (error token is ".235")

我已尝试过在不同论坛中发现的一些建议,例如使用带有和不带双引号的echo $line | cut -d" " -f7 | bc -l等。但是,错误仍然存​​在。 f7是一个正数,给出3位小数。删除小数或近似不是一个选项,因为我需要结果恰好为零(0.000)。

2 个答案:

答案 0 :(得分:2)

通常,您无法比较浮点数是否相等。这是因为十进制数字的二进制表示不精确,并且您得到舍入错误。这是大多数人给你的标准答案。

在这种特定情况下,您实际上不需要比较浮点数,因为您只是测试某些文本是否代表特定数字。由于你是shell,你可以使用常规字符串比较“0.000” - 假设你的数据以这种方式舍入 - 或者使用带有grep / egrep的正则表达式。像

这样的东西
egrep -q '0(|\.0+)'

将匹配0,0.0,0.00等,并将退出表示成功或失败,您可以在周围的if语句中使用:

if cut and pipe soup | egrep ... ; then
  ...
fi

答案 1 :(得分:1)

请改用字符串比较。替换:

-eq 0

使用:

= '0.000'

TZ:

评论的脚本部分:

for clus in $(ls *.cluster) ; do
    while read line ; do
        if [[ $(echo $line | cut -d" " -f11) -gt 0 ]] && [[ "$(echo $line | cut -d" " -f15 | bc -l)" = '0.000' ]] ; then
            cat $(echo $line | cut -d" " -f6).pdb >> test/$(echo $line | cut -d" " -f2)_pisa.pdb
        fi
    done < $clus
done

我的伪Python解释:

for clus in *.cluster:
    for line in clus:
        fields = line.split(' ')
        # field numbers are counting from 1 as in cut
        if int(field 11) > 0 and str(field 15) == '0.000':
            fin_name = (field 6) + '.pdb'
            fout_name = (field 2) + '_pisa.pdb'
            cat fin_name >> fout_name

那是你的意图吗?