检查两个对象在具有浮点值时是否相等?

时间:2016-07-11 23:31:08

标签: javascript binary floating-point equality

为我的Javascript程序编写一些处理二进制文件的测试用例现在我只是使用stringify来检查值和期望值是否相等:

JSON.stringify(val) === JSON.stringify(expected)

这个工作正常,除了我有浮点值。这就是:

Given Value:    [10,20,30,32.400001525878906,{"test":3,"asdf":23}]
Expected Value: [10,20,30,32.4,{"test":3,"asdf":23}]

Test Failed!

所以我想我不能再使用stringify来检查我的两个对象/数组是否相等。什么是检查两个可能深度嵌套的对象/数组是否相等同时还考虑浮点值的好方法?也就是说,如果两个浮点值相同或等于99.99%,则应视为相等。

1 个答案:

答案 0 :(得分:2)

您需要按顺序测试数组中的每个元素,并且您需要以递归方式对对象执行此操作。这通常被称为深度比较或深度相等。你应该能够使用一个检查比较类型的递归函数来做到这一点。

比较浮点值时,您需要使用容差。您可以通过获取彼此减去两个数字的绝对值,然后将其与您选择的固定公差值或称为epsilon的小数字进行比较来实现。

在JavaScript中,机器epsilon可用作Number.EPSILON,并且定义为1和大于1的最小数字之间的差异,可以表示为{ {1}}。大多数语言都提供类似的常量,通常用于基于容差的比较。

基于容差的比较将浮点比较从简单相等转换为减法和比较。如果你通常写

Number

你用绝对值和if (a === b) { ... } 写出来消除浮点怪异:

tolerance

如果var tolerance = Number.EPSILON; if (Math.abs(a - b) < tolerance) { ... } a之间的差异小于b,则视为相等。

对于更细微差别(但可能对你的情况有些过分)的方法,请参阅The Floating Point Guide's section on comparison。这里介绍的实现是用Java编写的,但可以轻松地移植到JavaScript中。