Perl中的Float比较问题

Dan*_*age 1 floating-point perl comparison

可能重复:
如何修复此Perl代码以便1.1 + 2.2 == 3.3?

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

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

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

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

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

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

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

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

我明白了

Test: '1.000000', '0', '1'
Run Code Online (Sandbox Code Playgroud)

Pau*_*lin 9

任何计算机语言教师都应该教你任何计算机语言的第一件事是,你不能为平等比较浮动.这对任何语言都是如此.浮点运算并不精确,看起来它们相同的两个浮点数在您无法看到它的某个无效数字中会有所不同.相反,你只能比较它们彼此接近 - 比如

if (abs(stats->{overall_simple_matching_coefficient)-1) < 0.0001)
Run Code Online (Sandbox Code Playgroud)

  • `eq`比较为字符串 - 如果将float转换为字符串会丢弃无关紧要的数字,`eq`将比较它们相等.但是依靠这是一件坏事 - 更好的是要知道你需要什么样的容忍度并将其与容忍度进行比较. (3认同)