JavaScript整数与小数乘法为何有时不精确?

来源:前端技术作者:俊华头衔:草根站长
导读:本期聚焦于小伙伴创作的《JavaScript整数与小数乘法为何有时不精确?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript整数与小数乘法为何有时不精确?》有用,将其分享出去将是对创作者最好的鼓励。

在JavaScript开发中,我们经常会遇到整数与小数乘法运算结果不符合预期的情况,比如0.1乘以3得到的结果不是0.3,这类问题困扰了很多刚接触这门语言的开发者,其根源和JavaScript的数值存储机制密切相关。

JavaScript整数与小数乘法为何有时不精确?

JavaScript数值的存储规则

JavaScript中所有数值都属于Number类型,采用的是IEEE 754双精度浮点数标准来存储,这种标准用64位二进制来表示一个数值,结构分为三部分:

  • 1位符号位:表示数值的正负
  • 11位指数位:表示数值的幂次
  • 52位尾数位:表示数值的有效数字部分

这种存储方式对于整数来说,只要数值范围在2的53次方以内,都可以被精确存储,但是小数部分在转换为二进制时,很多时候会出现无限循环的情况。

精度丢失的具体过程

我们以0.1乘以0.2为例,来看看精度丢失是怎么发生的:

第一步:十进制小数转二进制

0.1转换为二进制是无限循环的:0.00011001100110011...,0.2转换为二进制同样是无限循环的:0.0011001100110011...。

第二步:存储时截断尾数

因为尾数位只有52位,所以这两个无限循环的二进制数在存储时会被截断,只能保留前52位有效数字,这就导致了存储的0.1和0.2本身就和真实的十进制0.1、0.2存在微小误差。

第三步:乘法运算放大误差

当两个已经存在误差的数值进行乘法运算时,误差会被进一步放大,最终得到的结果就会和预期的精确值有偏差,也就是我们看到的0.1*0.2=0.30000000000000004。

常见的解决方案

针对这类精度问题,我们可以根据实际场景选择不同的解决方式:

1. 转为整数运算后再转回小数

这是最常用的方案,把参与运算的小数乘以10的n次方转为整数,运算完成后再除以10的n次方,避免直接进行小数运算。

// 计算0.1 * 0.2的精确结果
function multiplyPrecise(num1, num2) {
    // 获取两个数的小数位数
    const dec1 = (num1.toString().split('.')[1] || '').length;
    const dec2 = (num2.toString().split('.')[1] || '').length;
    // 计算需要放大的倍数
    const factor = Math.pow(10, dec1 + dec2);
    // 转为整数运算
    const int1 = num1 * Math.pow(10, dec1);
    const int2 = num2 * Math.pow(10, dec2);
    // 结果转回小数
    return (int1 * int2) / factor;
}
console.log(multiplyPrecise(0.1, 0.2)); // 输出0.2

2. 使用第三方精度库

如果项目中涉及大量高精度数值运算,推荐使用专门的库比如decimal.js,这类库封装了完善的精度处理逻辑,能避免手动处理带来的问题。

// 使用decimal.js进行运算
const Decimal = require('decimal.js');
const result = new Decimal(0.1).times(new Decimal(0.2));
console.log(result.toString()); // 输出0.2

3. 设置误差容忍范围

如果只是简单判断两个数值是否相等,不需要得到精确结果,可以设置一个很小的误差范围,只要两个数值的差值小于这个范围就认为相等。

function isNumberEqual(num1, num2, epsilon = 1e-10) {
    return Math.abs(num1 - num2) < epsilon;
}
console.log(isNumberEqual(0.1 * 0.2, 0.2)); // 输出true

注意事项

除了乘法之外,JavaScript的加减法、除法同样可能存在类似的精度问题,原理都是一样的,处理方式也通用。另外要注意,不要直接比较两个浮点数的相等性,比如0.1 + 0.2 === 0.3的结果是false,一定要用误差范围的方式判断。

如果运算的数值涉及金额等对精度要求极高的场景,优先选择转为整数运算或者使用专业精度库,避免直接使用原生的浮点数运算。

JavaScript浮点数精度Number类型小数乘法二进制转换修改时间:2026-06-15 15:21:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。