JavaScript金额运算出现精度丢失问题的解决方案

 更新时间:2025年03月21日 09:32:37   作者:心存の思念  
在 JavaScript 中,浮点数运算可能会产生精度丢失的问题,尤其在处理 金额计算 时,本文为大家整理了一些常用方法,有需要的小伙伴可以根据需求进行选择

1. 前言

在 JavaScript 中,浮点数运算可能会产生精度丢失的问题,尤其在处理 金额计算 时,这可能会导致严重的业务逻辑错误。例如:

console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.07 * 100); // 7.000000000000001
console.log(0.1 + 0.7 === 0.8); // false

这些问题主要是由于 JavaScript 使用 IEEE 754 双精度浮点数(64 位)来表示数字,某些小数无法用二进制精确表示,从而导致精度丢失。

本篇文章将深入剖析 JavaScript 金额计算精度丢失的原因,并提供多种 解决方案 来避免这些问题。

2. 为什么 JavaScript 计算金额会精度丢失

2.1 JavaScript 使用 IEEE 754 双精度浮点数

JavaScript 所有的 Number 类型 都遵循 IEEE 754 双精度浮点数(64 位)标准,它的存储方式如下:

符号位指数位尾数位(小数部分)
1 位11 位52 位

但 某些十进制小数无法用二进制精确表示,类似于 1/3 在十进制中是无限循环小数 0.3333...,而 0.1 在 二进制 下也会变成 无限循环小数:

0.1(十进制) = 0.000110011001100110011...(二进制 无限循环)

由于存储空间限制,JavaScript 只能截取前 52 位,导致数值被四舍五入,最终引发计算误差。

2.2 浮点运算错误示例

错误示例 1:0.1 + 0.2 ≠ 0.3

console.log(0.1 + 0.2); // 0.30000000000000004

解析:

  • 0.1 的二进制近似值:0.00011001100110011...
  • 0.2 的二进制近似值:0.0011001100110011...
  • 计算后,得到的二进制不是 精确的 0.3,而是 0.30000000000000004

错误示例 2:浮点乘法精度问题

console.log(0.07 * 100); // 7.000000000000001

0.07 转换成二进制后是 0.000100011110101110000101...,乘以 100 后的结果并不完全等于 7。

3. 解决方案

方案 1:使用整数运算(推荐)

核心思想:

避免小数计算,将小数转换为整数计算,计算完成后再转回小数。

function add(a, b) {
    return (a * 100 + b * 100) / 100;
}

console.log(add(0.1, 0.2)); // 0.3
console.log(add(0.07, 0.02)); // 0.09

适用场景:

  • 适用于 加法、减法、乘法、除法 计算。
  • 适用于 金额计算,例如:分(整数)代替元(小数)。

方案 2:使用 toFixed()(简单但不推荐)

console.log((0.1 + 0.2).toFixed(2)); // "0.30"
console.log((0.07 * 100).toFixed(2)); // "7.00"

缺点:

toFixed() 返回的是 字符串,如果要继续计算,还需转换回 Number 类型:

let result = Number((0.1 + 0.2).toFixed(2)); // 0.3

不能完全解决浮点运算的问题,只适用于 结果展示。

方案 3:使用 Number.EPSILON 进行误差修正

原理:

Number.EPSILON 是 JavaScript 最小的精度差值(约 2.22e-16),可用于修正浮点计算误差:

function add(a, b) {
    return Math.round((a + b + Number.EPSILON) * 100) / 100;
}

console.log(add(0.1, 0.2)); // 0.3
console.log(add(0.07, 0.02)); // 0.09

适用场景:

用于 浮点数精度修正,避免直接使用 toFixed()。

方案 4:使用 BigDecimal 类库(最佳方案)

JavaScript 原生 Number 无法解决所有精度问题,因此可以使用 BigDecimal 第三方库 来进行精准计算,例如 decimal.js。

安装:

npm install decimal.js

使用:

const Decimal = require('decimal.js');

console.log(new Decimal(0.1).plus(0.2).toNumber()); // 0.3
console.log(new Decimal(0.07).times(100).toNumber()); // 7

优点:

可以处理 任意精度 运算,特别适用于 金融计算。

方案 5:使用 ES11 BigInt(适用于整数金额计算)

BigInt 可用于 大数计算,但 不支持小数:

const a = BigInt(100); // 1.00 元
const b = BigInt(200); // 2.00 元

console.log((a + b) / BigInt(100)); // 3n (表示 3 元)

适用场景:

仅适用于 整数计算(如分单位),不适用于 小数计算。

4. 结论

方案适用场景优点缺点
整数运算(推荐)金额计算高效、适用范围广需要手动转换
toFixed()仅限展示简单易用结果为字符串,无法继续计算
Number.EPSILON浮点修正适用于加减运算不适用于复杂运算
decimal.js(最佳)任何精度计算高精度,API 强大需引入库
BigInt整数计算适用于大数运算不支持小数

5. 总结

JavaScript 的浮点运算容易导致金额计算误差,我们可以通过 整数运算、Number.EPSILON、BigDecimal 库等方式 来解决。

如果你正在开发电商、金融、结算系统,推荐使用 decimal.js 或整数运算,以保证计算精度。

到此这篇关于JavaScript金额运算出现精度丢失问题的解决方案的文章就介绍到这了,更多相关JavaScript精度丢失解决内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用CSS+JS实现融球+跟随鼠标效果实例

    使用CSS+JS实现融球+跟随鼠标效果实例

    JavaScript可以通过事件处理程序对用户的交互做出反应,例如点击按钮、鼠标移动等,下面这篇文章主要介绍了使用CSS+JS实现融球+跟随鼠标效果的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-03-03
  • quickjs调用lvgl函数的示例代码

    quickjs调用lvgl函数的示例代码

    这篇文章主要介绍了quickjs调用lvgl函数,实现本次使用quickjs的最主要目的,就是通过程序动态加载js,然后调用lvgl函数库,实现渲染,需要的朋友可以参考下
    2023-11-11
  • JavaScript实现随机点名小程序

    JavaScript实现随机点名小程序

    这篇文章主要介绍了JavaScript实现随机点名小程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • JavaScript也谈内存优化

    JavaScript也谈内存优化

    这篇文章主要介绍了JavaScript内存优化,主要是javascript的应用越来越复杂,内存问题所导致的卡顿、内存溢出等现象也变得不再陌生,所以说也谈内存优化,需要的朋友可以参考下
    2014-06-06
  • JavaScript 闭包原理和实践案例

    JavaScript 闭包原理和实践案例

    闭包(Closure)是 JavaScript 中最核心、最具特色也最容易引起困惑的概念之一,它既是前端面试的高频考点,也是理解 JavaScript 执行机制的关键,本文将从原理到实践,带你彻底掌握闭包的本质,感兴趣的朋友一起看看吧
    2025-10-10
  • 微信小程序webview组件交互,内联h5页面并网页实现微信支付实现解析

    微信小程序webview组件交互,内联h5页面并网页实现微信支付实现解析

    这篇文章主要介绍了小程序webview组件交互,内联h5页面并网页实现微信支付实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • 详解利用exif.js解决ios手机上传竖拍照片旋转90度问题

    详解利用exif.js解决ios手机上传竖拍照片旋转90度问题

    这篇文章主要介绍了详解利用exif.js解决ios手机上传竖拍照片旋转90度问题,有需要的朋友可以了解一下。
    2016-11-11
  • JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】

    JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】

    这篇文章主要介绍了JavaScript数据结构与算法之检索算法,结合实例形式分析了二分查找法、计算重复次数相关算法原理与使用技巧,需要的朋友可以参考下
    2019-02-02
  • JavaScript对象访问器的工作原理及使用方法

    JavaScript对象访问器的工作原理及使用方法

    今天来聊一下JavaScript中的对象访问器,JavaScript的主要功能之一是能够定义对象,这些对象可以封装属性和方法,本文将深入探讨 JavaScript 对象访问器是什么、它是如何工作的以及使用对象访问器的作用,需要的朋友可以参考下
    2024-06-06
  • 前端开发必须知道的JS之闭包及应用

    前端开发必须知道的JS之闭包及应用

    本文讲的是函数闭包,不涉及对象闭包(如用with实现)。如果你觉得我说的有偏差,欢迎拍砖,欢迎指教。
    2010-07-07

最新评论