JavaScript 浮点数运算 精度问题


Posted in Javascript onOctober 06, 2009

Js代码

<script type="text/javascript" language="javascript"> 
alert(1/3);//弹出: 0.3333333333333333 
alert(0.09999999 + 0.00000001);//弹出: 0.09999999999999999 
alert(-0.09999999 - 0.00000001);//弹出: -0.09999999999999999 
alert(0.012345 * 0.000001);//弹出: 1.2344999999999999e-8 
alert(0.000001 / 0.0001);//弹出: 0.009999999999999998 
</script> 
<script type="text/javascript" language="javascript"> 
    alert(1/3);//弹出: 0.3333333333333333 
    alert(0.09999999 + 0.00000001);//弹出: 0.09999999999999999 
    alert(-0.09999999 - 0.00000001);//弹出: -0.09999999999999999 
    alert(0.012345 * 0.000001);//弹出: 1.2344999999999999e-8 
    alert(0.000001 / 0.0001);//弹出: 0.009999999999999998 
</script> 
[code] 
按正常计算的话,除第一行外(因为其本身就不能除尽),其他都应该要得到精确的结果,从弹出的结果我们却发现不是我们想要的正确结果。为了解决浮点数运算不准确的问题,在运算前我们把参加运算的数先升级(10的X的次方)到整数,等运算完后再降级(0.1的X的次方)。现收集并整理贴于此,以备后用。 
加法 
Js代码 
[code] 
//说明: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的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 
//调用: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); 
} 
减法 
Js代码 
[code] 
//说明:javascript的减法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。 
//调用:accSub(arg1,arg2) 
//返回值:arg1减上arg2的精确结果 
function accSub(arg1,arg2){ 
return accAdd(arg1,-arg2); 
} 
//给Number类型增加一个sub方法,调用起来更加方便。 
Number.prototype.sub = function (arg){ 
return accSub(this,arg); 
} 
//说明:javascript的减法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。 
//调用:accSub(arg1,arg2) 
//返回值:arg1减上arg2的精确结果 
function accSub(arg1,arg2){ 
return accAdd(arg1,-arg2); 
} 
//给Number类型增加一个sub方法,调用起来更加方便。 
Number.prototype.sub = function (arg){ 
return accSub(this,arg); 
}

乘法
Js代码
//说明: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); 
} 
//说明: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); 
} 除法 
Js代码 
//说明: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的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。 
//调用: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); 
}

测试一把
Js代码
<script type="text/javascript" language="javascript"> 
/* 
alert(0.09999999 + 0.00000001);//弹出: 0.09999999999999999 
alert(-0.09999999 - 0.00000001);//弹出: -0.09999999999999999 
alert(0.012345 * 0.000001);//弹出: 1.2344999999999999e-8 
alert(0.000001 / 0.0001);//弹出: 0.009999999999999998 
*/ 
alert(0.09999999.add(0.00000001));//弹出: 0.1 
alert(-0.09999999.sub(0.00000001));//弹出: -0.09999998 
alert(0.012345.mul(0.000001));//弹出: 1.2345e-8 
alert(0.000001.div(0.0001));//弹出: 0.01 
</script>
Javascript 相关文章推荐
JavaScript 数组的 uniq 方法
Jan 23 Javascript
checkbox 多选框 联动实现代码
Oct 22 Javascript
通过location.replace禁止浏览器后退防止重复提交
Sep 04 Javascript
下雪了 javascript实现雪花飞舞
Aug 02 Javascript
谈谈JavaScript中的几种借用方法
Aug 09 Javascript
JavaScript表单验证开发
Nov 23 Javascript
js实现简单的网页换肤效果
Jan 18 Javascript
jQuery:unbind方法的使用详解
Aug 14 jQuery
js实现关闭网页出现是否离开提示
Dec 07 Javascript
对vue中v-if的常见使用方法详解
Sep 28 Javascript
vue中导出Excel表格的实现代码
Oct 18 Javascript
Vue项目自动转换 px 为 rem的实现方法
Oct 29 Javascript
面向对象的javascript(笔记)
Oct 06 #Javascript
js removeChild 障眼法 可能出现的错误
Oct 06 #Javascript
学习JS面向对象成果 借国庆发布个最新作品与大家交流
Oct 03 #Javascript
JQuery与Ajax常用代码实现对比
Oct 03 #Javascript
Jquery 设置标题的自动翻转
Oct 03 #Javascript
点击下载链接 弹出页面实现代码
Oct 01 #Javascript
点击文章内容处弹出页面代码
Oct 01 #Javascript
You might like
通过PHP CLI实现简单的数据库实时监控调度
2009/07/01 PHP
摘自织梦CMS的HTTP文件下载类
2015/08/08 PHP
使用PHP反射机制来构造&quot;CREATE TABLE&quot;的sql语句
2019/03/21 PHP
兼容多浏览器的iframe自适应高度(ie8 、谷歌浏览器4.0和 firefox3.5.3)
2009/11/04 Javascript
ExtJS4 表格的嵌套 rowExpander应用
2014/05/02 Javascript
javascript数组去重的方法汇总
2015/04/14 Javascript
Node.js编写组件的三种实现方式
2016/02/25 Javascript
使用Curl命令查看请求响应时间方法
2016/11/04 Javascript
关于webuploader插件使用过程遇到的小问题
2016/11/07 Javascript
原生js实现焦点轮播图效果
2017/01/12 Javascript
jQuery仿IOS弹出框插件
2017/02/18 Javascript
nodejs实现聊天机器人功能
2019/09/19 NodeJs
基于vue项目设置resolves.alias: '@'路径并适配webstorm
2020/12/02 Vue.js
pycharm 使用心得(三)Hello world!
2014/06/05 Python
详解python中executemany和序列的使用方法
2017/08/12 Python
对Python3中的print函数以及与python2的对比分析
2018/05/02 Python
关于Django ForeignKey 反向查询中filter和_set的效率对比详解
2018/12/15 Python
使用python3实现操作串口详解
2019/01/01 Python
pytorch 在sequential中使用view来reshape的例子
2019/08/20 Python
利用Python实现某OA系统的自动定位功能
2020/05/27 Python
python实现马丁策略回测3000只股票的实例代码
2021/01/22 Python
巧克力领导品牌瑞士莲美国官网:Lindt Chocolate美国
2016/08/25 全球购物
美国性感女装网站:bebe
2017/03/04 全球购物
亚马逊西班牙购物网站:amazon西班牙
2017/03/06 全球购物
Mankind西班牙男士护肤品网站:购买皮肤护理、护发和剃须
2017/04/27 全球购物
美国演唱会订票网站:Ticketmaster美国
2017/10/05 全球购物
日本小田急百货官网:Odakyu
2018/07/19 全球购物
意大利时尚奢侈品店:D’Aniello Boutique
2021/01/19 全球购物
行政专员岗位职责
2014/01/02 职场文书
平面设计专业求职信
2014/08/09 职场文书
六一领导慰问欢迎词
2015/01/26 职场文书
幼儿园教师节活动总结
2015/03/23 职场文书
2016新年晚会开场白
2015/12/03 职场文书
导游词之镇江-金山寺
2019/10/14 职场文书
教你怎么用python实现字符串转日期
2021/05/24 Python
利用JavaScript写一个简单计算器
2021/11/27 Javascript