C#测试方法中用AND运算符过滤float类型记录遇精度报错求助
解决C#中浮点数相等比较的精度警告问题
嘿,这个问题我太熟了!咱们来一步步拆解:
问题原因
出现这个警告的核心原因是浮点数(float/double)的存储机制:它们是用二进制近似表示十进制数值的,哪怕是看起来很简单的整数或小数,在二进制底层都可能是无限循环的近似值。直接用==做相等比较时,哪怕两个值逻辑上应该相等,也可能因为存储的微小精度差异导致判断失败——编译器正是在提醒你这个潜在的坑。
看你的代码,CoveragePolicyTypeId和Is953D这些字段存的都是离散的标识值(1、2、0),完全没必要用float类型,这才是问题的根源。
解决方案
方案1:改用整数类型(最推荐)
既然这些值都是整数标识,直接把类型换成int就能彻底解决问题,既消除警告,又让代码语义更清晰:
// 把const的类型从float改成int private const int FrontedCoveragePolicyTypeId = 2; private const int DirectlyWrittenCoveragePolicyTypeId = 1; private const int Is953DYes = 1; private const int Is953DNo = 0; [TestMethod] public void GetFedExciseExpenses_OnShore_Fronted_Test() { var result = _sut.GetFedExciseTaxExpenses(Industryid, DomicileId); Assert.IsTrue(result.Any()); // 直接用int的==比较,完全没有精度问题 var fedExciseExpense = result.Find(x => x.CoveragePolicyTypeId == FrontedCoveragePolicyTypeId && x.Is953D == Is953DNo); AssertFedExciseExpense(fedExciseExpense); } private static void AssertFedExciseExpense(FedExciseExpense expense) { Assert.IsNotNull(expense); Assert.IsNotNull(expense.Value); Assert.AreEqual(0, expense.Value); }
方案2:如果必须保留浮点数,使用容差比较
如果因为某些限制不能修改字段类型,那就不要直接用==,而是判断两个值的差的绝对值是否小于一个极小的阈值(比如float.Epsilon,或者根据业务场景自定义的小值,比如0.0001f):
var fedExciseExpense = result.Find(x => Math.Abs(x.CoveragePolicyTypeId - FrontedCoveragePolicyTypeId) < float.Epsilon && Math.Abs(x.Is953D - Is953DNo) < float.Epsilon);
不过还是强烈推荐方案1,因为用整数表示离散的标识值才是符合语义的设计,后续维护也更省心。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

