news 2026/7/7 15:46:33

JavaScript浮点数精度问题及解决方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript浮点数精度问题及解决方案

引言

在JavaScript开发中,我们经常会遇到一些看似简单的数学运算却产生意外结果的情况。例如,0.3 - 0.2 !== 0.12.55.toFixed(1)返回2.5而不是预期的2.6。这些问题源于JavaScript的数字表示方式——基于IEEE 754标准的双精度浮点数格式。本文将深入探讨这些问题的根源,并提供实用的解决方案。

问题一:0.3 - 0.2 !== 0.1

问题表现

console.log(0.3-0.2);// 输出: 0.09999999999999998console.log(0.3-0.2===0.1);// 输出: false

原因分析

JavaScript使用二进制浮点数表示所有数字。然而,像0.1、0.2和0.3这样的十进制小数在二进制中是无限循环的,无法被精确表示,内存中不可能无限存储,会进行截取,接下来可以看一下这些数据在内存。当进行减法运算时,这种不精确性会导致累积误差,使得结果与预期不符。

0.3.toString(2)// 存储的二进制 '0.010011001100110011001100110011001100110011001100110011'0.3.toPrecision(20)// toPrecision 用于将数字转换为字符串,并根据指定的有效数字位数进行格式化,很显然0.3实际存储的要小于0.3// '0.29999999999999998890'0.1.toString(2)// 存储的二进制 '0.0001100110011001100110011001100110011001100110011001101'0.1.toPrecision(20)// 小于0.1 '0.10000000000000000555'

解决方案

1. 使用整数运算

对于涉及货币或其他需要精确计算的场景,可以将数值转换为整数进行运算:

// 将数值乘以100转换为整数consta=30;// 代表0.30constb=20;// 代表0.20constresult=(a-b)/100;// 0.10console.log(result===0.1);// true
2. 四舍五入到固定小数位

通过四舍五入来消除微小误差:

constresult=Math.round((0.3-0.2)*100)/100;console.log(result===0.1);// true
3. 使用第三方库

对于复杂的十进制运算,可以使用专门的库如decimal.js或big.js:

// 使用decimal.jsconstDecimal=require('decimal.js');constresult=newDecimal(0.3).minus(newDecimal(0.2)).equals(newDecimal(0.1));console.log(result);// true

问题二:2.55.toFixed(1) 是 2.5 而不是 2.6

问题表现

console.log(1.55.toFixed(1));// 输出: "1.6"console.log(2.55.toFixed(1));// 输出: "2.5"

原因分析

toFixed()方法使用银行家舍入规则(四舍六入五成双),并且由于浮点数精度问题,2.55在内部可能被存储为略小于2.55的值,导致向下舍入。

解决方案

1. 自定义舍入函数

实现一个更符合直觉的舍入函数:

functioncustomRound(num,digits){constfactor=Math.pow(10,digits);return(Math.round(num*factor)/factor).toFixed(digits);}console.log(customRound(2.55,1));// 2.6
2. 添加微小增量

在调用toFixed之前给数字加上一个极小的值:

constnum=2.55;console.log((num+Number.EPSILON).toFixed(1));// "2.6"
3. 使用Intl.NumberFormat

利用国际化API进行格式化:

constformatter=newIntl.NumberFormat('en-US',{minimumFractionDigits:1,maximumFractionDigits:1});console.log(formatter.format(2.55));// "2.6"
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 13:46:07

考研数学高分指南:8K精编资料帮你突破学习瓶颈

还在为考研数学的复杂公式和繁多知识点而苦恼吗?📚 面对高等数学、线性代数和概率统计三大模块,你是不是经常感到无从下手?别担心,这份精心整理的8K打印版学习资料正是为你量身打造的提分利器! 【免费下载链…

作者头像 李华
网站建设 2026/7/7 20:20:18

抖音视频批量下载终极指南:一键保存无水印内容

抖音视频批量下载终极指南:一键保存无水印内容 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 还在为手动保存抖音视频而烦恼吗?想要批量下载喜欢的创作者所有作品却无从下手&#xf…

作者头像 李华
网站建设 2026/7/7 8:46:31

告别枯燥公式!用动画重新定义你的微积分学习体验

告别枯燥公式!用动画重新定义你的微积分学习体验 【免费下载链接】videos 项目地址: https://gitcode.com/GitHub_Trending/vi/videos 还在为微积分中那些抽象的导数符号和复杂的积分公式感到头疼吗?🤔 每次看到极限、微分、积分的定…

作者头像 李华
网站建设 2026/7/7 7:45:05

我的嵌入式权限踩坑实录

在 EBF6ULL 开发板上部署 Linux 驱动和测试程序时,我遭遇了一系列 “诡异” 报错,最终发现所有问题的根源都指向权限:​编译好的静态程序提示 command not found(实际是 /home 分区 noexec 挂载);​执行程序…

作者头像 李华
网站建设 2026/7/7 12:28:27

10、控制台脚本编程全解析

控制台脚本编程全解析 1. 控制台脚本概述 在商业环境中,时间就是金钱,开发图形用户界面(GUI)应用程序既耗时又昂贵。而控制台脚本,也称为基于文本或终端的脚本,是为在纯文本环境(如 Linux 控制台、Telnet 会话或 xterm 窗口)中运行而设计的。它们设计简单、构建快速,…

作者头像 李华
网站建设 2026/7/7 8:50:49

2025年企业微信SCRM性价比指南:选哪种最划算?

企业微信SCRM系统年投入动辄数十万,但60%的企业因选型失误陷入功能冗余却效果平平的困境。微盛作为服务过160家500强企业的企业微信生态最大服务商(腾讯四轮投资支持),结合这些头部企业的实战数据,拆解2025年高性价比S…

作者头像 李华