Perl中的Float比较问题

时间:2010-11-15 20:02:23

标签: perl floating-point comparison

  

可能重复:
  How do I fix this Perl code so that 1.1 + 2.2 == 3.3?

我正在研究Perl脚本,该脚本比较代表基因模型的字符串并打印出比较的摘要。如果基因模型完美匹配,我会打印出一个非常简洁的摘要,但如果它们不同,则摘要非常详细。

脚本查看变量的值以确定它是否应该执行简洁或详细的汇总 - 如果变量等于1,它应该打印简洁摘要;否则,应打印详细摘要。

由于值是数字(浮点数),我一直在使用==运算符进行比较。

if($stats->{overall_simple_matching_coefficient} == 1)
{
  print "Gene structures match perfectly!\n";
}

这适用于我的所有测试,甚至我现在正在运行的大多数新案例,但我发现一个奇怪的情况,其中值等于1,但上述比较失败。我无法弄清楚比较失败的原因,而且当我将==运算符更改为eq运算符时,它似乎工作正常。

我认为==用于数字比较,eq用于字符串比较。我在这里错过了什么吗?

更新:如果我在比较之前打印出值......

printf("Test: '%f', '%d', '%s'\n", $stats->{overall_simple_matching_coefficient}, $stats->{overall_simple_matching_coefficient}, $stats->{overall_simple_matching_coefficient});

......我明白了。

Test: '1.000000', '0', '1'

2 个答案:

答案 0 :(得分:9)

任何计算机语言教师应该首先教你任何计算机语言YOU CANNOT COMPARE FLOATS FOR EQUALIT Y.任何语言都是如此。浮点运算并不精确,看起来它们相同的两个浮点数在您无法看到它的某个无效数字中会有所不同。相反,你只能将它们 close 相互比较 - 比如

if (abs(stats->{overall_simple_matching_coefficient)-1) < 0.0001)

答案 1 :(得分:3)

如果在比较之前打印$stats->{overall_simple_matching_coefficient}的值,您会得到什么?如果是1,请尝试使用格式为"%20.10f"的printf。我强烈怀疑你在变量中积累了一些舍入误差(小于1e-6)并且它没有在数值上进行相等比较。但是当转换为字符串时,由于错误是小数点后6位,默认字符串格式是6位,所以它比较相等。