JS小数运算出现多为小数问题的解决方法


Posted in Javascript onJune 02, 2016

写在前面的话:

今天帮同事解决了一个问题,就是小数相乘出现很多位小数的问题;这个问题自己以前也遇到过,现在特意来总结一下;

Number类型:

Number类型是ECMAScript中最常用和最令人关注的类型了;这种类型使用IEEE754格式来表示整数和浮点数值(浮点数值在某些语言中也被成为双精度数值),为支持各种数据类型,ECMA-262定义了不同的数值面量格式。

十进制:
var intNum=10; //整数

八进制:
var octalNum1=070; //八进制的56
var octalNum2=079; //无效的八进制数值-解析为79

八进制字面量在严格模式下是无效的;

十六进制:
var hexNum1=0xA; //10
切记:在进行运算的时候,所有以八进制和十六进制表示的数值都最终被转换成十进制;
为什么操作小数会出现误差?
浮点数值的最高进度是17位小数,但在进行运算的时候其精确度却远远不如整数;整数在进行运算的时候都会转成10进制; 而Java和JavaScript中计算小数运算时,都会先将十进制的小数换算到对应的二进制,一部分小数并不能完整的换算为二进制,这里就出现了第一次的误差。待小数都换算为二进制后,再进行二进制间的运算,得到二进制结果。然后再将二进制结果换算为十进制,这里通常会出现第二次的误差。
所以(0.1+0.2)!=03

解决方式:

程序代码
除法函数,用来得到精确的除法结果
说明: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);
}

加法函数,用来得到精确的加法结果
说明: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);
}

在你要用的地方包含这些函数,然后调用它来计算就可以了。

比如你要计算:7*0.8 ,则改成 (7).mul(8)

其它运算类似,就可以得到比较精确的结果。
解决方式二:
比较常用的办法,toFixed(),toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。在我们计算的结果后面加上这个方法就OK了;但是对精度会有一丝影响,如果精度要求不高的话推荐使用;

Javascript 相关文章推荐
javascript之ESC(第二类混淆)
May 06 Javascript
js cookies 常见网页木马挂马代码 24小时只加载一次
Apr 13 Javascript
Jquery插件之Fancybox丰富的弹出层效果附源码下载
Dec 02 Javascript
jquery之别踩白块游戏的简单实现
Jul 25 Javascript
使用JS批量选中功能实现更改数据库中的status状态值(批量展示)
Nov 22 Javascript
js正则表达式验证表单【完整版】
Mar 06 Javascript
Bootstrap Table使用整理(一)
Jun 09 Javascript
浅谈JS中的反柯里化( uncurrying)
Aug 17 Javascript
AngularJS中controller控制器继承的使用方法
Nov 03 Javascript
node.js基础知识小结
Feb 26 Javascript
微信小程序Getuserinfo解决方案图解
Aug 24 Javascript
jquery 时间戳转日期过程详解
Oct 12 jQuery
jQuery easyUI datagrid 增加求和统计行的实现代码
Jun 01 #Javascript
jQuery 选择同时包含两个class的元素的实现方法
Jun 01 #Javascript
jquery ezUI 双击行记录弹窗查看明细的实现方法
Jun 01 #Javascript
jquery 实现滚动条下拉时无限加载的简单实例
Jun 01 #Javascript
sencha ext js 6 快速入门(必看)
Jun 01 #Javascript
Bootstrap3.0建站教程(一)之bootstrap表单元素排版
Jun 01 #Javascript
分享一个插件实现水珠自动下落效果
Jun 01 #Javascript
You might like
PHP超级全局变量数组小结
2012/10/04 PHP
使用PHP备份MySQL和网站发送到邮箱实例代码
2013/11/28 PHP
PHP中对于浮点型的数据需要用不同的方法解决
2014/03/11 PHP
php实现的SESSION类
2014/12/02 PHP
如何通过PHP实现Des加密算法代码实例
2020/05/09 PHP
基于jquery的地址栏射击游戏代码
2011/03/10 Javascript
javascript内存管理详细解析
2013/11/11 Javascript
JS控件ASP.NET的treeview控件全选或者取消(示例代码)
2013/12/16 Javascript
浅析JQuery UI Dialog的样式设置问题
2013/12/18 Javascript
Javascript改变CSS样式(局部和全局)
2013/12/18 Javascript
node.js中的fs.unlink方法使用说明
2014/12/15 Javascript
jquery实现图片左右切换的方法
2015/05/07 Javascript
jQuery实现的多屏图像图层切换效果实例
2015/05/07 Javascript
jQuery绑定事件on()与弹窗的简要概述
2016/04/27 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图和饼图的组合图效果示例【附demo源码下载】
2017/03/09 Javascript
Vue2.0 从零开始_环境搭建操作步骤
2017/06/14 Javascript
详解基于Koa2开发微信二维码扫码支付相关流程
2018/05/16 Javascript
nodejs 十六进制字符串型数据与btye型数据相互转换
2018/07/30 NodeJs
解决bootstrap中下拉菜单点击后不关闭的问题
2018/08/10 Javascript
Vue自定义弹窗指令的实现代码
2018/08/13 Javascript
使用 webpack 插件自动生成 vue 路由文件的方法
2019/08/20 Javascript
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
pytorch1.0中torch.nn.Conv2d用法详解
2020/01/10 Python
pytorch 实现张量tensor,图片,CPU,GPU,数组等的转换
2020/01/13 Python
在pycharm中实现删除bookmark
2020/02/14 Python
如何把外网python虚拟环境迁移到内网
2020/05/18 Python
HTML5中在title标题标签里设置小图标的方法
2020/06/23 HTML / CSS
欧洲最古老的鞋厂:Peter Kaiser
2019/11/05 全球购物
电子信息科学专业自荐信
2014/01/30 职场文书
个人工作作风整改措施思想汇报
2014/10/13 职场文书
2014年幼儿园后勤工作总结
2014/11/10 职场文书
2014年民主评议党员工作总结
2014/12/02 职场文书
三下乡个人总结
2015/03/04 职场文书
暂停营业通知
2015/04/25 职场文书
Python3 类型标注支持操作
2021/06/02 Python
python 镜像环境搭建总结
2022/09/23 Python