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 相关文章推荐
Mootools 1.2教程 类(一)
Sep 15 Javascript
css值转换成数值请抛弃parseInt
Oct 24 Javascript
jquery命令汇总,方便使用jquery的朋友
Jun 26 Javascript
一个网页标题title的闪动提示效果实现思路
Mar 22 Javascript
js加密解密字符串可自定义密码因子
May 13 Javascript
JavaScript中的各种操作符使用总结
May 26 Javascript
javascript类型系统——日期Date对象全面了解
Jul 13 Javascript
JavaScript数据操作_浅谈原始值和引用值的操作本质
Aug 23 Javascript
手机端点击图片放大特效PhotoSwipe.js插件实现
Aug 24 Javascript
使用BootStrapValidator完成前端输入验证
Sep 28 Javascript
canvas滤镜效果实现代码
Feb 06 Javascript
JavaScript中的 new 命令
May 22 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
PHPShop存在多个安全漏洞
2006/10/09 PHP
PHP Directory 函数的详解
2013/03/07 PHP
PHP中mb_convert_encoding与iconv函数的深入解析
2013/06/21 PHP
php ci框架验证码实例分析
2013/06/26 PHP
php获取服务器端mac和客户端mac的地址支持WIN/LINUX
2014/05/15 PHP
神盾加密解密教程(三)PHP 神盾解密工具
2014/06/08 PHP
php使用COPY函数更新配置文件的方法
2015/06/18 PHP
php抽象类用法实例分析
2015/07/07 PHP
PHP 与 UTF-8 的最佳实践详细介绍
2017/01/04 PHP
详解php几行代码实现CSV格式文件输出
2017/07/01 PHP
JS 动态获取节点代码innerHTML分析 [IE,FF]
2009/11/30 Javascript
JQuery教学之性能优化
2014/05/14 Javascript
不能不知道的10个angularjs英文学习网站
2016/03/23 Javascript
BootStrap modal模态弹窗使用小结
2016/10/26 Javascript
js 性能优化之快速响应的用户界面
2017/02/15 Javascript
JS正则替换去空格的方法
2017/03/24 Javascript
微信小程序 支付后台java实现实例
2017/05/09 Javascript
快速解决Vue项目在IE浏览器中显示空白的问题
2018/09/04 Javascript
vue将后台数据时间戳转换成日期格式
2019/07/31 Javascript
thinkjs微信中控之微信鉴权登陆的实现代码
2019/08/08 Javascript
Vue2.0 $set()的正确使用详解
2020/07/28 Javascript
python对url格式解析的方法
2015/05/13 Python
Python爬虫通过替换http request header来欺骗浏览器实现登录功能
2018/01/07 Python
在Python 中同一个类两个函数间变量的调用方法
2019/01/31 Python
python输入多行字符串的方法总结
2019/07/02 Python
Python实现基于SVM的分类器的方法
2019/07/19 Python
python pillow模块使用方法详解
2019/08/30 Python
Python socket连接中的粘包、精确传输问题实例分析
2020/03/24 Python
利用python批量爬取百度任意类别的图片的实现方法
2020/10/07 Python
乌克兰设计师和品牌的服装:Love&Live
2020/04/14 全球购物
联想智利官方网站:Lenovo Chile
2020/06/03 全球购物
银行实习生的自我评价
2014/01/13 职场文书
工程项目经理任命书
2014/06/05 职场文书
街道社区活动报告
2015/02/05 职场文书
2016自主招生校长推荐信范文
2015/03/23 职场文书
人事部:年度述职报告范文
2019/07/12 职场文书