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与asp.net(c#)互相调用方法
Dec 13 Javascript
Javascript base64编码实现代码
Dec 02 Javascript
js读取被点击次数的简单实例(从数据库中读取)
Mar 07 Javascript
jquery map方法使用示例
Apr 23 Javascript
js获取页面传来参数的方法
Sep 06 Javascript
详解Bootstrap四种图片样式
Jan 04 Javascript
jQuery遍历DOM节点操作之filter()方法详解
Apr 14 Javascript
深入理解JS实现快速排序和去重
Oct 17 Javascript
详解Angularjs 如何自定义Img的ng-load 事件
Feb 15 Javascript
ThinkPHP+jquery实现“加载更多”功能代码
Mar 11 Javascript
日期时间范围选择插件:daterangepicker使用总结(必看篇)
Sep 14 Javascript
详解element-ui 表单校验 Rules 配置 常用黑科技
Jul 11 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字符串函数系列之nl2br(),在字符串中的每个新行 (\n) 之前插入 HTML 换行符br
2011/11/10 PHP
如何使用Gitblog和Markdown建自己的博客
2015/07/31 PHP
PHP购物车类Cart.class.php定义与用法示例
2016/07/20 PHP
PHP守护进程化在C和PHP环境下的实现
2017/11/21 PHP
laravel自定义分页的实现案例offset()和limit()
2019/10/15 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
用js实现键盘方向键翻页功能的代码
2007/06/03 Javascript
jQuery timers计时器简单应用说明
2010/10/28 Javascript
遍历jquery对象的代码分享
2011/11/02 Javascript
Javascript实现关联数据(Linked Data)查询及注意细节
2013/02/22 Javascript
JavaScript中的replace()方法使用详解
2015/06/06 Javascript
jQuery 常用代码集锦(必看篇)
2016/05/16 Javascript
Jquery on方法绑定事件后执行多次的解决方法
2016/06/02 Javascript
微信小程序 欢迎页面的制作(源码下载)
2017/01/09 Javascript
jquery实现图片轮播器
2017/05/23 jQuery
JS获取鼠标坐标并且根据鼠标位置不同弹出不同内容
2017/06/12 Javascript
微信小程序实现点击图片旋转180度并且弹出下拉列表
2018/11/27 Javascript
JS实现页面侧边栏效果探究
2021/01/08 Javascript
[46:00]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第一局
2016/03/03 DOTA
Python中处理字符串的相关的len()方法的使用简介
2015/05/19 Python
Python模拟自动存取款机的查询、存取款、修改密码等操作
2018/09/02 Python
python找出完数的方法
2018/11/12 Python
python的常用模块之collections模块详解
2018/12/06 Python
python爬虫刷访问量 2019 7月
2019/08/01 Python
python返回数组的索引实例
2019/11/28 Python
Kmeans均值聚类算法原理以及Python如何实现
2020/09/26 Python
python 读取、写入txt文件的示例
2020/09/27 Python
机电一体化专业应届本科生求职信
2013/09/27 职场文书
兰兰过桥教学反思
2014/02/08 职场文书
班级道德讲堂实施方案
2014/02/24 职场文书
幼儿园教师自我鉴定
2014/03/20 职场文书
2014光棍节大学生联谊活动方案
2014/10/10 职场文书
党员个人党性分析材料
2014/12/18 职场文书
关于python爬虫应用urllib库作用分析
2021/09/04 Python
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL
开发者首先否认《遗弃》被取消的传言
2022/04/11 其他游戏