如何在C++的Google Test中匹配双精度向量元素并规避精度问题?
针对Google Mock中浮点数精度的匹配器解决方案
当然有啦!Google Mock早就考虑到浮点数精度这个头疼的问题了,提供了好几个专门的匹配器,完全可以替代ASSERT_DOUBLE_EQ的作用,配合ASSERT_THAT和ElementsAre一起用,完美规避精度陷阱。
常用的浮点数匹配器
DoubleEq(expected):和ASSERT_DOUBLE_EQ完全等价,会使用Google Test默认的双精度浮点数误差阈值(基于机器epsilon的合理范围)来比较,自动处理浮点数的微小精度差异。NanSensitiveDoubleEq(expected):和DoubleEq逻辑一致,但会把两个NaN视为相等(默认DoubleEq会认为NaN不等于任何值,包括另一个NaN),适合需要处理NaN的场景。WithinAbs(expected, absolute_error):允许你自定义绝对误差范围,只要实际值与期望值的差的绝对值 ≤absolute_error,就判定为匹配。WithinRel(expected, relative_error):用相对误差来比较,适合处理不同数量级的浮点数(比如比较0.0001和0.0001001,或者1000和1001),相对误差的计算遵循行业通用规则。
结合ElementsAre的向量比较示例
如果你要比较std::vector<double>的元素,只需要把ElementsAre里的直接数值替换成对应的浮点数匹配器就行:
#include <gmock/gmock.h> #include <vector> TEST(MyTest, VectorDoubleComparison) { std::vector<double> actual_vec{0.1, 0.2}; // 使用DoubleEq匹配器处理精度问题 ASSERT_THAT(actual_vec, testing::ElementsAre( testing::DoubleEq(0.1), testing::DoubleEq(0.2) )); // 也可以自定义绝对误差,比如允许0.0001的误差 std::vector<double> another_vec{0.10005, 0.19995}; ASSERT_THAT(another_vec, testing::ElementsAre( testing::WithinAbs(0.1, 0.0001), testing::WithinAbs(0.2, 0.0001) )); }
批量处理元素的小技巧
如果向量里所有元素都需要用同一个精度规则匹配,还可以用Each匹配器简化代码:
// 示例:验证向量中所有元素都在1.0的±0.01范围内 std::vector<double> batch_vec{0.995, 1.003, 0.998}; ASSERT_THAT(batch_vec, testing::Each(testing::WithinAbs(1.0, 0.01)));
内容的提问来源于stack exchange,提问作者motam79
相关产品推荐
相关产品推荐

