您当前位置:首页 > 文章中心 > SCSCMS

关于js浮点数计算精度不准确问题的解决办法

稿件来源: 阳光企业网站管理系统   撰稿作者: 太阳光   发表日期: 2017-09-27   阅读次数: 537   查看权限: 游客查看

今天在计算商品价格的时候再次遇到js浮点数计算出现误差的问题,因此在网上收集了一些处理浮点数精度的文章。以方便后续查阅。

先看一个实例:
0.1 + 0.2 = 0.30000000000000004
这就是经典的浮点数问题,原理什么的就不讲了,先看一个网上解决办法。

    //加法  
    Number.prototype.add = function(arg){
        var r1,r2,m;
        try{r1=this.toString().split(".")[1].length}catch(e){r1=0}
        try{r2=arg.toString().split(".")[1].length}catch(e){r2=0}
        m=Math.pow(10,Math.max(r1,r2))
        return (this*m+arg*m)/m
    }

var a = 0.1,b = a.add(0.2);好像没多大问题了。但是经测试仍有bug

var a = 19.36,b = a.add(601.19);
console.log(b);//返回620.5500000000001

主要原因在于 601.19*100 = 60119.00000000001
于是网络中有各种修复,比如修复toFixed(修复函数还挻复杂的),或添加函数处理。其实根本用不着,小小改动取个整即可:

    //修正版:加法  
    Number.prototype.add = function(arg){
        var r1,r2,m;
        try{r1=this.toString().split(".")[1].length}catch(e){r1=0}
        try{r2=arg.toString().split(".")[1].length}catch(e){r2=0}
        m=Math.pow(10,Math.max(r1,r2));
        return Math.round(this*m+arg*m)/m;
    }

顺便写个数组里各元素之和方法:

    function addition(arr) {
        if(Object.prototype.toString.call(arr)!== "[object Array]"){
            throw 'arr必须是数组';
        }
        let m = 0,c = 0;
        arr.forEach(a => {
            if(isNaN(a))throw '含有非法数值';
            try{
                m = Math.max(m,a.toString().split(".")[1].length)
            } catch (e) {}
        });
        m = Math.pow(10,m);
        arr.forEach(a => {c += a * m;});
        return Math.round(c) / m;
    }

 

修复原生toFixed函数

Number.prototype.toFixed = function (len){
    //len 必须是正整数或者0,可以是字符串数字
    if((len | 0) == len && len >= 0){
        var _s = this + '',_i = len;
        var reg = _s.match(new RegExp("^(\\d+\\.\\d{"+len+"})(\\d)"));
        if(reg){
            _s = (1 * reg[1].replace('.','') + (reg[2] > 4 ? 1 : 0))/Math.pow(10,len) + '';
        }
        //不够小数位,要补零
        _s += _s.indexOf('.') !== -1 ? '':'.';//添加小数点
        while(_i --){_s += '0'} //添加足够的零
        return _s.substring(0,_s.indexOf('.') + (len ? ++len:0));
    }else{
        throw 'toFixed() digits argument must be get 0';
    }
};

 

 

关键词: 浮点数,加法   编辑时间: 2017-10-19 19:08:31

  • 感到高兴

    4

    高兴
  • 感到支持

    4

    支持
  • 感到搞笑

    4

    搞笑
  • 感到不解

    4

    不解
  • 感到谎言

    4

    谎言
  • 感到枪稿

    4

    枪稿
  • 感到震惊

    4

    震惊
  • 感到无奈

    4

    无奈
  • 感到无聊

    4

    无聊
  • 感到反对

    5

    反对
  • 感到愤怒

    4

    愤怒
50%(4)
50%(4)
共有0 条评论 发言请遵守【相关规定

网友评论

会员头像
发 表同步腾讯微博    验证码:  点击更新请先登陆
  • 暂无评论
关闭模块文章图片 article Pictrue
  • 我的妈妈爸爸
  • 基于koa2+mysql+vue2.0+Element阳光内容管理系统
  • 代码覆盖率工具 Istanbul 入门教程
  • 全栈工程师的武器——MEAN
  • 9款超炫的 CSS3 复选框(Checkbox)
  • 微信开发在线翻译功能
  • CSS3那些不为人知的高级属性
  • 给easyui的datebox添加清空事件
  • flash写字效果
  • kendoUI系列教程之DropDownList下拉菜单
  • kendoUI系列教程之datetimepicker日期时间选择
  • kendoUI系列教程之datepicker日期选择
  • kendoUI系列教程之combobox下拉列表框
  • kendoUI系列教程之colorpicker
  • kendoUI系列教程之calendar日历表
  • kendoUI系列教程之autocomplete自动补齐