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

从C#向SQL Server存储液体计量数据时,如何选择数值类型与精度?

优化方案:减少舍入误差的实践建议

核心原则

  • 保留原始数据,避免中间环节过早舍入
  • 统一C#与SQL Server的计算精度
  • 仅在最终展示/结算环节做必要舍入

1. 数据库数据类型设计

原始数据列(优先存储)

  • 重量列:秤精度为0.1g,定义为 Decimal(7,1),可覆盖0.0~99999.9g的称量范围,完全保留原始读数无舍入。
  • 密度列:精度0.01g/mL,定义为 Decimal(5,2),足够覆盖常见液体密度(如0.70~2.00g/mL)。
  • 液体类型列:可选存字符串(如VARCHAR(20))或关联字典表,用于后续追溯密度来源。

计算结果列(可选)

如果需要直接存储体积,不要用Decimal(9,4),改用 Decimal(10,6):

  • 重量是1位小数、密度是2位小数,重量/密度的结果最多会生成3位以上小数(例如0.1/1.23≈0.081301),6位小数能完全保留计算精度,避免存储时的舍入损失。

金额列

体积与单价相乘后的金额,定义为 Decimal(12,4),足够覆盖绝大多数液体的单价计算需求,最终展示时可按需舍入到2位小数。


2. C#计算逻辑优化

针对你的GetVolume函数,做以下调整:

private Decimal GetVolume(string liquid, string netWeight)
{
    // 避免正则解析失败导致的异常
    var match = Regex.Match(netWeight, @"\d+\.*\d*");
    if (!match.Success || !Decimal.TryParse(match.Value, out Decimal weight))
    {
        throw new InvalidOperationException("无法解析秤的重量读数");
    }

    // 避免除以0风险,强制覆盖所有液体类型
    Decimal density = liquid switch
    {
        "Liquid 1" => 1.00M,
        "Liquid 2" => 1.23M,
        _ => throw new ArgumentOutOfRangeException(nameof(liquid), "不支持的液体类型")
    };

    // 直接返回高精度计算结果,不提前舍入
    return weight / density;
}
  • 增加解析失败的异常处理,避免程序崩溃
  • 用模式匹配替换switch,同时消除density初始值为0的隐患
  • 保留Decimal的原生高精度计算结果,不做中间舍入

3. 减少累积误差的关键操作

  • 优先存储原始数据:不要只存体积,把重量、液体类型、称量时间全部存入数据库。后续如果需要修正密度、调整精度,可直接用原始数据重新计算,避免历史舍入误差累积。
  • 用SQL原生计算总用量:统计长期总使用量时,不要在C#中循环累加每条记录的体积,直接用SQL的聚合函数计算:
    SELECT SUM(weight / density) AS TotalVolume
    FROM LiquidWeights
    WHERE LiquidType = 'Liquid 1' AND MeasureTime BETWEEN '2024-01-01' AND '2024-12-31'
    
    数据库会用自身Decimal精度完成计算,减少客户端与服务器之间的数据传输精度损失。
  • 延迟舍入时机:仅在给用户展示、生成财务报表时,对体积或金额做舍入(比如用Math.Round(volume, 4)或Math.Round(amount, 2)),中间计算全程保留高精度。

4. 验证与测试

  • 边界值测试:用秤的最小读数(0.1g)除以最小密度(如0.01g/mL),验证存储和计算结果是否为10.0
  • 累积测试:多次称量相同重量,对比累加体积与总重量直接计算的结果是否一致
  • 一致性验证:确保C#与SQL Server的Decimal计算结果无差异,避免因精度设置不同导致偏差

内容的提问来源于stack exchange,提问作者longdistancerunner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:52:44