浮点测试断言 - 为什么这些"相同"数组失败?

时间:2014-05-19 10:00:52

标签: php phpunit

我在PHPUnit中使用 assertSame()来比较数据库结果和期望值。结果是浮点数。

PHPUnit返回此消息(但我无法发现任何差异):

Failed asserting that Array (
    '1_1' => 11.111111111111
    '1_2' => 33.333333333333
    '1_3' => 55.555555555556
    '1_4' => 0.0
    '1_5' => null
    '1_total' => 100.0
) is identical to Array (
    '1_1' => 11.111111111111
    '1_2' => 33.333333333333
    '1_3' => 55.555555555556
    '1_4' => 0.0
    '1_5' => null
    '1_total' => 100.0
)

为什么这会失败以及比较浮点值数组的正确方法是什么?

3 个答案:

答案 0 :(得分:13)

assertEquals对于这种情况有一个$ floating_delta参数:

$this->assertEquals($expected_array, $actual_array, '', 0.00001);

PHPUnit docs

答案 1 :(得分:1)

问题几乎可以肯定是浮点精度。在print_r中,只显示了这么多位数。如果显示了所有有效位,情况可能是这样的:

Failed asserting that Array (
    '1_1' => 11.1111111111110347
    '1_2' => 33.3333333333331678
    '1_3' => 55.5555555555562773
    '1_4' => 0.0
    '1_5' => null
    '1_total' => 100.0
) is identical to Array (
    '1_1' => 11.1111111111110346
    '1_2' => 33.3333333333331679
    '1_3' => 55.5555555555562771
    '1_4' => 0.0
    '1_5' => null
    '1_total' => 100.0
)

每个浮点比较 - 特别是相等 - 必须考虑缺乏无限精度。

if ($var == 0.005)     /* just plain wrong! */

if (abs ($var, 0.005) < 0.001)    /*  more correct  */

if (abs ($var, 0.005) < 0.0001)    /* maybe more correct, depending on application */

if (abs ($var, 0.005) < 0.0000001)    /* possibly more appropriate */

答案 2 :(得分:0)

除非有人有更好的建议,否则我会假设这是一个浮点精度错误,并遵循PHP手册建议: do not compare floating point numbers directly for equality

所以我自己的解决方案是在比较之前对数组值进行舍入。