Catch v2.13.1浮点数比较正确方式及断言异常问题咨询
理解Catch2 v2.13.1中浮点比较的行为
这问题其实戳中了Catch2里Approx比较逻辑的一个关键细节——它默认是同时结合绝对误差和相对误差来判断的,而且只要满足其中一个条件就会通过断言。咱们一步步拆解你的疑惑:
先算清楚核心差值
首先,你给出的两个数值:
1147332687.7189338和1147332688.4281545
它们的差值是:1147332688.4281545 - 1147332687.7189338 ≈ 0.7092,这个值远大于你设置的0.0001绝对误差门槛,但前两个断言却通过了,问题就出在相对误差上。
Catch2 Approx的默认逻辑
Catch2 v2中Approx的默认规则是:
- 相对误差(epsilon)默认是
1e-5(也就是0.001%) - 绝对误差(margin)默认是
0 - 判断逻辑是:只要差值 ≤ 绝对误差 OR 差值 ≤ 相对误差 × 较大的那个数值,断言就会通过
咱们来算一下相对误差的容忍度:
以较大的数值1147332688.4281545为例,它的1e-5相对误差是:1147332688.4281545 × 1e-5 ≈ 11473.3269
这个值比你的差值0.7092大得多,所以即使你设置了margin(0.0001),相对误差的条件已经满足,断言自然就通过了。第二个没设置margin的断言,同样是因为相对误差条件满足,所以也通过了。
第三个断言为什么符合预期失败?
你写的第三个断言:
REQUIRE(abs(1147332687.7189338 - 1147332688.4281545) <= Approx(0).margin(0.0001));
这里的逻辑是直接比较差值和Approx(0).margin(0.0001),而Approx(0)的相对误差判断对0来说没有意义(因为0乘任何数都是0),所以它只会检查绝对误差——差值0.7092远大于0.0001,断言就失败了,这和你的预期一致。
如何让前两个断言按预期失败?
如果你想只检查绝对误差,需要手动关闭相对误差的判断,通过epsilon(0)来实现:
// 关闭相对误差,只检查绝对误差是否≤0.0001 REQUIRE(1147332687.7189338 == Approx(1147332688.4281545).epsilon(0).margin(0.0001));
这样一来,只有当差值≤0.0001时断言才会通过,你的测试就会像预期那样失败了。
内容的提问来源于stack exchange,提问作者Inquisitor
相关产品推荐
相关产品推荐

