如何进行JavaScript 浮点数及运算精度调整
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,本篇文章为大家展示了如何进行JavaScript 浮点数及运算精度调整,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。JavaScript 只有一种数字类型 N
千家信息网最后更新 2025年02月01日如何进行JavaScript 浮点数及运算精度调整
本篇文章为大家展示了如何进行JavaScript 浮点数及运算精度调整,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的。浮点数的精度问题不是JavaScript特有的,因为有些小数以二进制表示位数是无穷的。
十进制 二进制 0.1 0.0001 1001 1001 1001 … 0.2 0.0011 0011 0011 0011 … 0.3 0.0100 1100 1100 1100 … 0.4 0.0110 0110 0110 0110 … 0.5 0.1 0.6 0.1001 1001 1001 1001 …
所以比如 1.1,其程序实际上无法真正的表示 ‘1.1′,而只能做到一定程度上的准确,这是无法避免的精度丢失:1.09999999999999999
在JavaScript中问题还要复杂些,这里只给一些在Chrome中测试数据:
console.log(1.0-0.9 == 0.1) //false console.log(1.0-0.8 == 0.2) //false console.log(1.0-0.7 == 0.3) //false console.log(1.0-0.6 == 0.4) //true console.log(1.0-0.5 == 0.5) //true console.log(1.0-0.4 == 0.6) //true console.log(1.0-0.3 == 0.7) //true console.log(1.0-0.2 == 0.8) //true console.log(1.0-0.1 == 0.9) //true
那如何来避免这类 1.0-0.9 != 0.1 的非bug型问题发生呢?下面给出一种目前用的比较多的解决方案, 在判断浮点运算结果前对计算结果进行精度缩小,因为在精度缩小的过程总会自动四舍五入:
(1.0-0.9).toFixed(digits) // toFixed() 精度参数digits须在0与20之间 console.log(parseFloat((1.0-0.9).toFixed(10)) === 0.1) //true console.log(parseFloat((1.0-0.8).toFixed(10)) === 0.2) //true console.log(parseFloat((1.0-0.7).toFixed(10)) === 0.3) //true console.log(parseFloat((11.0-11.8).toFixed(10)) === -0.8) //true
写成一个方法:
//通过isEqual工具方法判断数值是否相等 function isEqual(number1, number2, digits){ digits = digits == undefined? 10: digits; // 默认精度为10 return number1.toFixed(digits) === number2.toFixed(digits); } console.log(isEqual(1.0-0.7, 0.3)); //true //原型扩展方式,更喜欢面向对象的风格 Number.prototype.isEqual = function(number, digits){ digits = digits == undefined? 10: digits; // 默认精度为10 return this.toFixed(digits) === number.toFixed(digits); } console.log((1.0-0.7).isEqual(0.3)); //true
接下来,再来试试浮点数的运算,
console.log(1.79+0.12) //1.9100000000000001 console.log(2.01-0.12) //1.8899999999999997 console.log(1.01*1.3) //1.3130000000000002 console.log(0.69/10) //0.06899999999999999
解决方案:
//加法函数,用来得到精确的加法结果 //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 //调用:accAdd(arg1,arg2) //返回值:arg1加上arg2的精确结果 function accAdd(arg1,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 (arg1*m+arg2*m)/m } //给Number类型增加一个add方法,调用起来更加方便。 Number.prototype.add = function (arg){ return accAdd(arg,this); } //减法函数,用来得到精确的减法结果 //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。 //调用:accSub(arg1,arg2) //返回值:arg1减去arg2的精确结果 function accSub(arg1,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)); //last modify by deeka //动态控制精度长度 n=(r1>=r2)?r1:r2; return ((arg1*m-arg2*m)/m).toFixed(n); }
//除法函数,用来得到精确的除法结果 //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。 //调用:accDiv(arg1,arg2) //返回值:arg1除以arg2的精确结果 function accDiv(arg1,arg2){ var t1=0,t2=0,r1,r2; try{t1=arg1.toString().split(".")[1].length}catch(e){} try{t2=arg2.toString().split(".")[1].length}catch(e){} with(Math){ r1=Number(arg1.toString().replace(".","")) r2=Number(arg2.toString().replace(".","")) return (r1/r2)*pow(10,t2-t1); } } //给Number类型增加一个div方法,调用起来更加方便。 Number.prototype.div = function (arg){ return accDiv(this, arg); } //乘法函数,用来得到精确的乘法结果 //说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 //调用:accMul(arg1,arg2) //返回值:arg1乘以arg2的精确结果 function accMul(arg1,arg2) { var m=0,s1=arg1.toString(),s2=arg2.toString(); try{m+=s1.split(".")[1].length}catch(e){} try{m+=s2.split(".")[1].length}catch(e){} return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m) } //给Number类型增加一个mul方法,调用起来更加方便。 Number.prototype.mul = function (arg){ return accMul(arg, this); }
//验证一下: console.log(accAdd(1.79, 0.12)); //1.91 console.log(accSub(2.01, 0.12)); //1.89 console.log(accDiv(0.69, 10)); //0.069
console.log(accMul(1.01, 1.3)); //1.313
改造之后,可以愉快地进行浮点数加减乘除操作了~
上述内容就是如何进行JavaScript 浮点数及运算精度调整,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。
结果
精确
精度
点数
函数
加法
方法
运算
明显
两个
乘法
时候
类型
除法
减法
问题
调整
二进制
内容
技能
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
伊春市网络安全和信息化
采血dna数据库
深圳软件开发解决方案介绍
有名的网络安全论坛
中国知网的数据库
电脑安装盗版软件开发商发函
玩家怎么自建arma3服务器
重庆提供软件开发流程公司
我的世界网易服务器斗罗大陆生存
海阳软件开发商
怎样看连接服务器所有电脑名
软件开发与测试工作量
苹果软件开发者费用是多少
服务器数据库ip地址
网络安全等级测评师面试题
福州中邦网络技术
3d软件开发有哪些
清远服务器除尘设备
网络安全和文明惩处措施
长春网络安全招聘
用于政府的网络安全股
软件开发选择什么样的公司
青海双线服务器云服务器
大学网络安全薄弱
无线网络安全模拟器
网络信息安全法 境外服务器
品牌软件开发售后保障
软件开发的作文例子
网络安全行业期刊
计算机网络技术毕业生级别