js 计算精度问题
一 浮点计算精读出现的问题枚举
0.1 + 0.2 // 0.30000000000000004 not 0.3
0.3 - 0.2 // 0.09999999999999998 not 0.1
1.005 * 100 //100.49999999999999 not 100.5 , 所以用 Math.round(1.005*100)/100 得到的也是1 not 1.01
0.69 / 10 // 0.06899999999999999 not 0.069
1.005.toFixed(2) // '1.00' not '1.01' (四舍五入:采用银行家算法 - 不准确)
二 js 浮点计算 精度出现精读问题的原因
js所有数字包括整数浮点数只有一种类型 - Number类型,它遵循IEEE 754标准,使用固定的64位固定长度来表示,也就是标准的double 双精度浮点数。(单精读 是float 32位) 。
这样的存储结构优点是可以归一化处理整数和小数,节省存储空间。
64位比特又可分为三个部分:
符号位S:第 1 位是正负数符号位(sign),0代表正数,1代表负数
指数位E:中间的 11 位存储指数(exponent),用来表示次方数
尾数位M:最后的 52 位是尾数(mantissa),超出的部分自动进一舍零
所以产生误差的原因:由于有一些浮点数用二进制表示时是无穷的,当浮点数转化为二进制进行存储时,会把超过53位之后的进行合并导致精读丢失。
三 js 浮点运算解决方案 (保留多少位数小数,末尾实现四舍五入)
方法一: 自定义函数
function toFixed(n, d) {
if (n > Number.MAX_SAFE_INTEGER || n < Number.MIN_SAFE_INTEGER) {
throw new Error('超过js安全计算值范围,此函数暂不支持!');
}
const radix = 10 ** d;
let num = math.floor(n * radix);
const a = String(n).split('.');
if (a[1] && a[1].length >= d) {
if (Number(a[1][d]) >= 5) {
num += 1;
}
}
return num / radix;
}
方法二 利用mathjs 库
import { create, all, round } from 'mathjs';
const config = {
number: 'BigNumber',
precision: 64,
};
const mathJs = create(all, config);
// number 和 bignumber类型
// mathJs.evaluate('0.1 + 0.2'); // 0.3
// 默认保留两位小数,实现四舍五入
export const math = (expression, precision = 2) => {
return round(mathJs.number(mathJs.evaluate(expression)), precision);
};
math('0.1 + 0.2'); // 0.3
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具