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

如何解决浮点数x.999999小数位导致的重量计算精度问题?

解决浮点数精度问题的保留两位小数函数优化

问题背景

  • 浮点数精度异常:计算49.8 - 12.45时,结果为37.34999999999999而非预期的37.35
  • 原截断函数处理后,四次减法无法归零:
    • 49.8 - 12.45 → 37.34
    • 37.34 - 12.45 → 24.89
    • 24.89 - 12.45 → 12.44
    • 12.44 无法再减12.45
  • 逻辑矛盾:49.8 / 4 = 12.45,理论上四次减法应能归零

原函数代码:

function threeDecimals(num) {
  const multipliedNum = num * 100;
  const truncatedNum = Math.trunc(multipliedNum);
  const num3decimals = truncatedNum / 100;
  return num3decimals;
}

优化方案

需求:当数值第三位小数为9时进位保留两位小数,否则沿用原截断逻辑。

优化后的函数代码

function optimizedRound(num) {
  // 放大1000倍,便于提取第三位小数
  const multipliedBy1000 = num * 1000;
  const integerPart = Math.trunc(multipliedBy1000);
  const decimalPart = multipliedBy1000 - integerPart;
  
  // 处理浮点数精度误差,近似判断第三位小数是否为9
  if (Math.abs(decimalPart - 0.9) < 0.0001) {
    // 进位:放大100倍后加1再截断
    return Math.trunc(num * 100 + 1) / 100;
  } else {
    // 原截断逻辑
    return Math.trunc(num * 100) / 100;
  }
}

代码说明

  1. 放大1000倍:将第三位小数转化为可直接判断的数值部分,避免浮点数精度干扰
  2. 近似匹配判断:由于浮点数存储特性,直接判断decimalPart === 0.9可能失效,用极小阈值做近似比对
  3. 进位逻辑:当第三位小数为9时,通过num*100+1实现进位后再截断,保证两位小数的准确性
  4. 截断逻辑保留:其他场景沿用原截断方式,避免无意义的进位影响计算逻辑

测试验证

针对问题场景测试:

  • optimizedRound(49.8 - 12.45) 返回 37.35
  • 后续减法流程:
    • 37.35 - 12.45 → 24.90
    • 24.90 - 12.45 → 12.45
    • 12.45 - 12.45 → 0
      四次减法后成功归零,符合逻辑预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 01:15:51