您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax | jQuery | 小程序 |

JS中toFixed()方法四舍五入的精度问题详解

51自学网 2022-02-21 13:40:01
  javascript

踩的坑

最近工作中,在计算一个商品的折扣价格,有时候总是出现价格会有一分钱的差异,涉及钱的问题都是比较敏感的,经过排查,最后发现竟然是 JS 原生的 toFixed 方法的问题。

好家伙,这都啥规律啊。。。(⊙o⊙)

填坑方法

先不着急去探究其中的问题,既然发现了问题,那就先把 Bug 修复了先,原生方法用不了,就自己写一个呗,还不是分分钟的事情,哈哈哈!

/** * 保留小数点几位数, 自动补零, 四舍五入 * @param num: 数值 * @param digit: 小数点后位数 * @returns string */ function myFixed(num, digit) {  if(Object.is(parseFloat(num), NaN)) {    return console.log(`传入的值:${num}不是一个数字`);  }  num = parseFloat(num);  return (Math.round((num + Number.EPSILON) * Math.pow(10, digit)) / Math.pow(10, digit)).toFixed(digit);}

什么样的坑?

好了,既然 Bug 解决完了,下面我们就来探索一下 toFixed 其中的奥秘。

呃...首先,Em...百度一下吧,面向百度编程工程师,果然一查大把结果,看来是个经典问题了。

经过一番了解得知,原来是 toFixed 方法采用的四舍五入,并不是我们理解的字面上的四舍五入。而 toFixed 方法它是采用一种诡异的方法 "四舍六入五取偶" ,也叫银行家算法,这是什么个意思呢?

完整说法:"四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一"。

大概意思是:当舍去位的数值 ≤4 时舍去,当它 ≥6 时加上,可当它 =5 时,则根据 5 后面的数字来定;当 5 后有非零数字时,舍 5 入 1;当 5 后无有效数字时,需要再分两种情况:5 前为偶数,舍 5 不进;5 前为奇数,舍 5 入 1 。

根据这个规则,我在浏览器上又跑了一些测试,但却还是感觉不对。

// 五前是偶数,没有舍去?console.log(1.00000065.toFixed(7)); // 1.0000007 错误console.log(1.000000065.toFixed(8)); // 1.00000007 错误// 五前是奇数,没有进一?console.log(1.00000015.toFixed(7)); // 1.0000001 错误console.log(1.000000015.toFixed(8)); // 1.00000001 错误

这到底为啥?真是让人摸不着头脑。。。(
下载地址:
微信小程序map地图使用方法详解
jQuery插件实现手风琴二级菜单

万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。