#独家
JS前端数字计算精度丢失问题,请问各位是怎么解决的?

2023-08-02 0 3,014

比如计算百分比,乘除法,js计算有小数点,精度会丢失,通过toFixed可以截取小数后几位,但是会四舍五入,而toPrecision则需要指定数字长度。现在要保留小数点后2位,请问怎么处理

let n = 123.123;
console.log(n.toPrecision(4)) // 123.1
let n = 123.126;
console.log(n.toFixed(2)) // 123.13

期望结果:
let n = 123.1266646635525563;
// 123.12

所谓“没有完美的算法,只有合适的场景”,浮点数字(小数)就是个很好的例子。

我们知道,按照目前的规范,JS 无法直接完美的处理小数。但是实际上,我们往往也不需要它“完美”处理小数。比如,以记账为例,我们通常只关心小数点后两位,也就是“分”,再细的,我们关注它意义不大,投入产出比太低。那么我们就可以把所有数字 * 100,取整后保存,带来的误差非常低。

所以,讨论小数精度问题,要看具体的需求。只要满足需求,怎么保存都可以。

类似的方法,函数其实很多,比如说可以用Math.floor函数,将结果向下取整,最后再除以100。这样可以保留小数点后2位并且不进行四舍五入。
可以这样:

let n = 123.1266646635525563;
let result = Math.floor(n * 100) / 100;
console.log(result); // 123.12

或者用字符串的substring函数截取小数点后的位数也是可以的,相对刚刚纯数字的方法多了一个转换步骤,相对复杂一点点,但有时候用得上,将len n转换为s字符串,然后在里面找到小数点的位置,最后再输出。

let n = 123.1266646635525563;
let result = n.toString();
let decimalIndex = result.indexOf('.') + 1;
result = result.substring(0, decimalIndex + 2);
console.log(parseFloat(result)); // 123.12

自定义计算函数:

function multiply(a, b) {
    let m = 0;
    const s1 = a.toString();
    const s2 = b.toString();
    try { m += s1.split(".")[1].length } catch (e) {}
    try { m += s2.split(".")[1].length } catch (e) {}
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}

function divide(a, b) {
    let t1 = 0;
    let t2 = 0;
    try { t1 = a.toString().split(".")[1].length } catch (e) {}
    try { t2 = b.toString().split(".")[1].length } catch (e) {}
    const r1 = Number(a.toString().replace(".", ""));
    const r2 = Number(b.toString().replace(".", ""));
    return multiply((r1 / r2), Math.pow(10, t2 - t1));
}

function add(a, b) {
    let c = 0;
    let d = 0;
    try { c = a.toString().split(".")[1].length } catch (e) {}
    try { d = b.toString().split(".")[1].length } catch (e) {}
    const m = Math.pow(10, Math.max(c, d));
    return (multiply(a, m) + multiply(b, m)) / m;
}

function subtract(a, b) {
    let c = 0;
    let d = 0;
    try { c = a.toString().split(".")[1].length } catch (e) {}
    try { d = b.toString().split(".")[1].length } catch (e) {}
    const m = Math.pow(10, Math.max(c, d));
    const n = (c >= d) ? c : d;
    return ((multiply(a, m) - multiply(b, m)) / m).toFixed(n);
}

let n = 123.1266646635525563;
let result = multiply(n, 100);
result = Math.floor(result);
result = divide(result, 100);
console.log(result); // 123.12

回复

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

1. 有软官网所有资源来源于开发团队,加入会员即可下载使用!如有问题请联系右下角在线客服!
2. 有软官方保障所有软件都通过人工亲测,为每位会员用户提供安全可靠的应用软件、游戏资源下载及程序开发服务。
3. 有软团队针对会员诉求,历经多年拥有现今开发成果, 每款应用程序上线前都经过人工测试无误后提供安装使用,只为会员提供安全原创的应用。
4. PC/移动端应用下载后如遇安装使用问题请联系右下角在线客服或提交工单,一对一指导解决疑难。

有软官网_用软件,找有软 技术分享 JS前端数字计算精度丢失问题,请问各位是怎么解决的? https://www.jiaruvip.com/2346.html

有软应用商店是经过官方安全认证,保障正版软件平台

相关资源

官方客服团队

为您解决烦忧 - 24小时在线 专业服务