You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:51:11