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 相关文章推荐
JS短路原理的应用示例 精简代码的途径
Dec 13 Javascript
jquery实现弹出层完美居中效果
Mar 03 Javascript
jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween
Dec 03 Javascript
JavaScript动态创建form表单并提交的实现方法
Dec 10 Javascript
jQuery实现的调整表格行tr上下顺序
Jan 10 Javascript
js设置和获取自定义属性的方法
Oct 20 Javascript
微信JSAPI Ticket接口签名详解
Jun 28 Javascript
解决canvas画布使用fillRect()时高度出现双倍效果的问题
Aug 03 Javascript
深入理解vue中slot与slot-scope的具体使用
Jan 26 Javascript
Vue单页应用引用单独的样式文件的两种方式
Mar 30 Javascript
javascript实现切割轮播效果
Nov 28 Javascript
vue模块移动组件的实现示例
May 20 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
索尼SONY SRF-S83/84电路分析和打磨
2021/03/02 无线电
PHP PDOStatement对象bindpram()、bindvalue()和bindcolumn之间的区别
2014/11/20 PHP
php实现按指定大小等比缩放生成上传图片缩略图的方法
2014/12/15 PHP
基于thinkPHP框架实现留言板的方法
2016/10/17 PHP
php简单处理XML数据的方法示例
2017/05/19 PHP
PHP基于socket实现客户端和服务端通讯功能
2017/07/13 PHP
php实现微信模板消息推送
2018/03/30 PHP
jQuery事件 delegate()使用方法介绍
2012/10/30 Javascript
struts2+jquery+json实现异步加载数据(自写)
2013/06/24 Javascript
struts2+jquery组合验证注册用户是否存在
2014/04/30 Javascript
JS/Jquery判断对象为空的方法
2015/06/11 Javascript
JS组件Bootstrap按钮组与下拉按钮详解
2016/05/10 Javascript
JS获取复选框的值,并传递到后台的实现方法
2016/05/30 Javascript
深入理解bootstrap框架之第二章整体架构
2016/10/09 Javascript
Webpack中css-loader和less-loader的使用教程
2017/04/27 Javascript
vue-resource 拦截器(interceptor)的使用详解
2017/07/04 Javascript
JS写XSS cookie stealer来窃取密码的步骤详解
2017/11/20 Javascript
angularjs实现table增加tr的方法
2018/02/27 Javascript
常用的 JS 排序算法 整理版
2018/04/05 Javascript
在vue里使用codemirror遇到的问题
2018/11/01 Javascript
在layui下对元素进行事件绑定的实例
2019/09/06 Javascript
Vue ElementUI实现:限制输入框只能输入正整数的问题
2020/07/31 Javascript
vue+vant 上传图片需要注意的地方
2021/01/03 Vue.js
[07:39]第一届亚洲邀请赛回顾视频
2017/02/14 DOTA
python里大整数相乘相关技巧指南
2014/09/12 Python
在Python中用split()方法分割字符串的使用介绍
2015/05/20 Python
用Python编写简单的微博爬虫
2016/03/04 Python
Python初学者需要注意的事项小结(python2与python3)
2018/09/26 Python
Django中template for如何使用方法
2021/01/31 Python
美国宠物商店:Wag.com
2016/10/25 全球购物
Capitol Lighting的1800lighting.com:住宅和商业照明
2019/04/10 全球购物
优秀毕业自我鉴定
2014/02/15 职场文书
机械设计及其自动化专业求职信
2014/06/09 职场文书
酒店员工辞职信范文
2015/02/28 职场文书
2016暑期政治学习心得体会
2016/01/23 职场文书
导游词之西江千户苗寨
2019/12/24 职场文书