JS当中toFixed()方法5不进位问题处理

最近发现JS当中toFixed()方法存在一些问题,采用原生的Number对象的原型对象上的toFixed()方法时,规则并不是所谓的“四舍五入”或者是“四舍六入五成双”,以谷歌浏览器为例:

alert(1.5451.toFixed(2));//输出 1.55
alert(1.545.toFixed(2)); //输出 1.54
alert(1.5551.toFixed(2)); //输出 1.56
alert(1.555.toFixed(2)); //输出 1.55
即:小数点后第三位5后面有数时进位,后面没数时舍弃不进位

注:
“四舍六入五成双”:也即“4舍6入5凑偶”这里“四”是指≤4 时舍去,"六"是指≥6时进上,"五"指的是根据5后面的数字来定,当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:①5前为奇数,舍5入1;②5前为偶数,舍5不进。(0是最小的偶数) 。百度百科上涉及的几个例子在实际情况下确实成立,但不科学,并不能覆盖所有的情况。

在浮点数末尾≤4或者≥6的情况下的舍入没有争议,但当末尾正好等于5的情况下可谓混乱之极(与浏览器有关,同样的方法,在谷歌和IE上会有不同显示)。
总结:众所周知,遵循IEEE754数值格式的语言的浮点计算会出现精度损耗的通病,ES也并非独此一家,因此尽量不要进行某个特定浮点数值的测试,如:0.1+0.2;
解决方案:重写Number.prototype.toFixed()方法:

Number.prototype.toFixed=function (d) { 
    var s=this+""; 
    if(!d)d=0; 
    if(s.indexOf(".")==-1)s+="."; 
    s+=new Array(d+1).join("0"); 
    if(new RegExp("^(-|\\+)?(\\d+(\\.\\d{0,"+(d+1)+"})?)\\d*$").test(s)){
        var s="0"+RegExp.$2,pm=RegExp.$1,a=RegExp.$3.length,b=true;
        if(a==d+2){
            a=s.match(/\d/g); 
            if(parseInt(a[a.length-1])>4){
                for(var i=a.length-2;i>=0;i--){
                    a[i]=parseInt(a[i])+1;
                    if(a[i]==10){
                        a[i]=0;
                        b=i!=1;
                    }else break;
                }
            }
            s=a.join("").replace(new RegExp("(\\d+)(\\d{"+d+"})\\d$"),"$1.$2");

        }if(b)s=s.substr(1); 
        return (pm+s).replace(/\.$/,"");
    }return this+"";

}

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在JavaScript中,toFixed()方法用于将数字转换为指定小数位数的字符串表示。该方法接受一个参数,即要保留的小数位数。\[1\] 例如,如果我们有一个数字324.12,并使用toFixed(1),则结果将是324.1。同样,如果我们使用toFixed(3),结果将是324.120。\[1\] 但是,toFixed()方法处理某些情况下可能会出现精度问题。为了解决这个问题,有人重写了toFixed()方法,通过扩大原数字的倍数来保留指定的小数位数,并使用Math.floor()方法来获取最接近的整数。\[2\] 但是,有候在使用toFixed()方法,可能会出现死循环的问题,这可能是因为在toFixed()方法中回调了toFixed()方法,导致无法退出循环。\[3\] 因此,在使用toFixed()方法,需要注意这些问题,并根据具体情况选择合适的解决方案。 #### 引用[.reference_title] - *1* [js中toFixed()方法](https://blog.csdn.net/greek7777/article/details/120464309)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [JS的toFixed方法](https://blog.csdn.net/qq_40805231/article/details/101271638)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值