解决js加减乘除精度丢失问题

公共类, 将科学计数法的数字转为字符串(以下加减乘除依赖该方法)

javascript 复制代码
var toNonExponential = (num)=> {
    if(num == null) {
        return num;
    }
    if(typeof num == "number") {
        var m = num.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/);
        return num.toFixed(Math.max(0, (m[1] || '').length - m[2]));
    }else {
        return num;
    }
 }

乘(以下加减除依赖该方法)

javascript 复制代码
var floatMultiply = (arg1, arg2) => {
    arg1 = Number(arg1);
    arg2 = Number(arg2);
    if ((!arg1 && arg1!==0) || (!arg2 && arg2!==0)) {
        return null;
    }
    arg1 = toNonExponential(arg1);
    arg2 = toNonExponential(arg2);
    var n1, n2;
    var r1, r2; // 小数位数
    try {
        r1 = arg1.toString().split(".")[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    } catch (e) {
        r2 = 0;
    }
    n1 = Number(arg1.toString().replace(".", ""));
    n2 = Number(arg2.toString().replace(".", ""));
    return n1 * n2 / Math.pow(10, r1 + r2);
}

javascript 复制代码
var floatDivide = (arg1, arg2) => {
    arg1 = Number(arg1);
    arg2 = Number(arg2);
    if (!arg2) {
        return null;
    }
    if (!arg1 && arg1!==0) {
        return null;
    }else if(arg1===0) {
        return 0;
    }
    arg1 = toNonExponential(arg1);
    arg2 = toNonExponential(arg2);
    var n1, n2;
    var r1, r2; // 小数位数
    try {
        r1 = arg1.toString().split(".")[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    } catch (e) {
        r2 = 0;
    }
    n1 = Number(arg1.toString().replace(".", ""));
    n2 = Number(arg2.toString().replace(".", ""));
    return floatMultiply((n1 / n2), Math.pow(10, r2 - r1));
}

javascript 复制代码
var floatAdd = (arg1, arg2) => {
    arg1 = Number(arg1) || 0;
    arg2 = Number(arg2) || 0;
    arg1 = toNonExponential(arg1);
    arg2 = toNonExponential(arg2);
    var r1, r2, m;
    try {
        r1 = arg1.toString().split(".")[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    } catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2));
    return (floatMultiply(arg1, m) + floatMultiply(arg2, m)) / m;
}

javascript 复制代码
var floatSub = (arg1, arg2) => {
    arg1 = Number(arg1) || 0;
    arg2 = Number(arg2) || 0;
    arg1 = toNonExponential(arg1);
    arg2 = toNonExponential(arg2);
    var r1, r2, m, n;
    try {
        r1 = arg1.toString().split(".")[1].length;
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    } catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2));
    // 动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((floatMultiply(arg1, m) - floatMultiply(arg2, m)) / m).toFixed(n);
}

参考:https://blog.csdn.net/ycclydy/article/details/123580326

相关推荐
发现一只大呆瓜几秒前
React-深度拆解 React路由:从实战进阶到底层原理
前端·react.js·面试
不甜情歌2 分钟前
搞懂 Promise:告别回调嵌套,再也不怕异步代码乱成麻
前端·javascript
野草arthas4 分钟前
什么是视觉层次?为什么需要它?
前端
发现一只大呆瓜16 分钟前
React-手把手带你实现 Keep-Alive 效果
前端·react.js·面试
酉鬼女又兒38 分钟前
入门前端CSS 媒体查询全解析:从入门到精通,打造完美响应式布局(可用于备赛蓝桥杯Web应用开发)
前端·css·职场和发展·蓝桥杯·前端框架·html5·媒体
Dxy12393102161 小时前
HTML常用标签详解
前端·html
毛骗导演1 小时前
@tencent-weixin/openclaw-weixin 插件深度解析(一):认证与会话管理机制
前端·架构
spencer_tseng1 小时前
Vue node_modules
javascript·vue.js
wefly20171 小时前
告别本地环境!m3u8live.cn一键实现 M3U8 链接预览与调试
前端·后端·python·音视频·m3u8·前端开发工具
SuperEugene1 小时前
前端 console 日志规范实战:高效调试 / 垃圾 log 清理与线上安全避坑|编码语法规范篇
开发语言·前端·javascript·vue.js·安全