文章分类 Classification
关于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)
- 暂无评论
文章图片 article Pictrue
网友评论