js精度丢失

118 阅读1分钟

javaScript 中的精度丢失问题主要源于 IEEE 754 浮点数表示标准。这是现代计算机普遍使用的浮点数表示方法,它规定了如何在二进制中存储和处理小数。

浮点数表示的基础知识

  1. IEEE 754 标准:
  • JavaScript 的 Number 类型是基于 IEEE 754 的 64 位双精度浮点数
  • 一个浮点数用 64 位存储
  1. 二进制存储的局限性:
  • 并非所有的小数都能用二进制精确表示。例如:十进制的 0.1 在二进制中是一个 无限循环小数,计算机只能截断并近似存储
  • 类似地,0.2 也会被近似存储
  1. 运算中的累积误差:
  • 当执行加减乘除时,近似值的误差可能被放大,从而导致结果不精确。

工作中常用解决方法

  1. 转换为整数计算(用的不多,仅用于了解)
  • 通过将浮点数转换为整数进行计算,避免精度丢失,最后再转换回浮点数。
function add(a, b) {
  const factor = Math.pow(10, Math.max(decimalPlaces(a), decimalPlaces(b)));
  return (a * factor + b * factor) / factor;
}

function decimalPlaces(num) {
  const str = num.toString();
  return str.includes('.') ? str.split('.')[1].length : 0;
}

console.log(add(0.1, 0.2)); // 0.3
  1. 使用 toFixed 方法(适用于简单运算且小数位固定)
  • 使用 toFixed 将结果格式化为固定小数位数的字符串,并根据需要转换为数字。
  • 注意toFixed 会进行四舍五入。
  1. 使用第三方库decimal.js(适用于高精度需求或复杂运算)