最近做项目,要用到js的加、减、乘、除的计算,发现js浮点数计算会有一些误差。

  网上有很多文章都有js浮点数计算误差的解决方法,说能解决这个问题,But……。比如一个加法函数,如下:

 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
}

此方法在很多人的博客里都有,也有很多人转摘,不知道他们是否真正的使用了,真正的进行了测试,这个方法是不能解决所有js浮点数计算误差的,比如:alert(accAdd(268.34,0.83));

  由于项目要用,所以参考了一些思路与方法,对js的加、减、乘、除的精确计算方法进行了如下处理,废话不多说,代码如下:

(function () {
var calc = {
/*
函数,加法函数,用来得到精确的加法结果
说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
参数:arg1:第一个加数;arg2第二个加数;d要保留的小数位数(可以不传此参数,如果不传则不处理小数位数)
调用:Calc.Add(arg1,arg2,d)
返回值:两数相加的结果
*/
Add: function (arg1, arg2) {
arg1 = arg1.toString(), arg2 = arg2.toString();
var arg1Arr = arg1.split("."), arg2Arr = arg2.split("."), d1 = arg1Arr.length == 2 ? arg1Arr[1] : "", d2 = arg2Arr.length == 2 ? arg2Arr[1] : "";
var maxLen = Math.max(d1.length, d2.length);
var m = Math.pow(10, maxLen);
var result = Number(((arg1 * m + arg2 * m) / m).toFixed(maxLen));
var d = arguments[2];
return typeof d === "number" ? Number((result).toFixed(d)) : result;
},
/*
函数:减法函数,用来得到精确的减法结果
说明:函数返回较为精确的减法结果。
参数:arg1:第一个加数;arg2第二个加数;d要保留的小数位数(可以不传此参数,如果不传则不处理小数位数
调用:Calc.Sub(arg1,arg2)
返回值:两数相减的结果
*/
Sub: function (arg1, arg2) {
return Calc.Add(arg1, -Number(arg2), arguments[2]);
},
/*
函数:乘法函数,用来得到精确的乘法结果
说明:函数返回较为精确的乘法结果。
参数:arg1:第一个乘数;arg2第二个乘数;d要保留的小数位数(可以不传此参数,如果不传则不处理小数位数)
调用:Calc.Mul(arg1,arg2)
返回值:两数相乘的结果
*/
Mul: function (arg1, arg2) {
var r1 = arg1.toString(), r2 = arg2.toString(), m, resultVal, d = arguments[2];
m = (r1.split(".")[1] ? r1.split(".")[1].length : 0) + (r2.split(".")[1] ? r2.split(".")[1].length : 0);
resultVal = Number(r1.replace(".", "")) * Number(r2.replace(".", "")) / Math.pow(10, m);
return typeof d !== "number" ? Number(resultVal) : Number(resultVal.toFixed(parseInt(d)));
},
/*
函数:除法函数,用来得到精确的除法结果
说明:函数返回较为精确的除法结果。
参数:arg1:除数;arg2被除数;d要保留的小数位数(可以不传此参数,如果不传则不处理小数位数)
调用:Calc.Div(arg1,arg2)
返回值:arg1除于arg2的结果
*/
Div: function (arg1, arg2) {
var r1 = arg1.toString(), r2 = arg2.toString(), m, resultVal, d = arguments[2];
m = (r2.split(".")[1] ? r2.split(".")[1].length : 0) - (r1.split(".")[1] ? r1.split(".")[1].length : 0);
resultVal = Number(r1.replace(".", "")) / Number(r2.replace(".", "")) * Math.pow(10, m);
return typeof d !== "number" ? Number(resultVal) : Number(resultVal.toFixed(parseInt(d)));
}
};
window.Calc = calc;
}());

  目前以上代码在项目中使用,还没有发现有什么问题。如果你觉得有问题或有具体的数据验证有问题,请联系!

实现js浮点数加、减、乘、除的精确计算(网上很多文章里的方法是不能解决所有js浮点数计算误差的)的更多相关文章

  1. IEEE 754 浮点数加减运算

    电子科技大学 - 计算机组成原理 小数的十进制和二进制转换 移码 定义:[X]移 = X + 2n ( -2n ≤ X < 2n ) X为真值,n为整数的位数 数值位和X的补码相同,符号位与补码 ...

  2. php小数加减精度问题,比特币计算精度问题

    php小数加减精度问题,比特币计算精度问题 在php开发时,有小数加减的场景.结果发现不能够等于预想的值,bccomp比较二个高精确度数字.语法: int bccomp(string left ope ...

  3. Java浮点数float,bigdecimal和double精确计算的精度误差问题总结

    (转)Java浮点数float,bigdecimal和double精确计算的精度误差问题总结 1.float整数计算误差 案例:会员积分字段采用float类型,导致计算会员积分时,7位整数的数据计算结 ...

  4. js 浮点数加减问题

      /**  ** 加法函数,用来得到精确的加法结果  ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显.这个函数返回较为精确的加法结果.  ** 调用:accAd ...

  5. JS日期加减指定天数

    JS中没有直接操作日期加减的方法,只能通过Date对象获取当前天数加减之后setDate,以此来达到操作日期的目的 JS中对指定日期加减指定天数,具体方法如下: function addDate(da ...

  6. js 时间加减

    //js格式化时间 "yyyy-MM-dd hh:mm:ss" Date.prototype.Format = function (fmt) { var o = { "M ...

  7. js日期加减

    先补充下基础知识: var myDate = new Date(); //myDate默认返回当前时间 myDate.getYear(); //获取当前年份(2位) myDate.getFullYea ...

  8. 记录Js动态加载页面.append、html、appendChild、repend添加元素节点不生效以及解决办法

    今天再优化blog页面的时候添加了个关注按钮和图片,但是页面上这个按钮和图片时有时无,本来是搞后端的,被这个前端的小问题搞得抓耳挠腮的! 网上各种查询解决方案,把我解决问题的艰辛历程分享出来,希望大家 ...

  9. Js 日期加减天数

    <SCRIPT language="javascript"> function addDate(dd,dadd){ var a = new Date(dd) a = a ...

随机推荐

  1. 火狐下<a>标签里嵌套的<select>不能选的bug

    今天遇到了这个问题,网上一找就找到原因了:在狐火下<a>标签里嵌套的<select>不能选 可是我查找这个问题过程中依然饶了一些时间,原因是在<a>标签没有写hre ...

  2. 对于JavaScript对象的prototype和__proto__的理解

    一.Object和Function的关系: 刚学JavaScript的时候,看书上说JavaScript中万物皆对象,而javascript中的其他对象都是从Object继承而来,包括内置对象.瞬间觉 ...

  3. shopnc怎么开启伪静态 shopnc开启伪静态的方法

    最近要给一个shopnc网站开启伪静态,用的是shopnc b2b2c,在网上搜索了好多shopnc开启伪静态的方法,但都是针对shaopnc c2c的,没有关于shopnc b2b2c的,最后终于找 ...

  4. The Time in Words

    def main(): time = ["one", "two", "three", "four", "fiv ...

  5. 字符串:各种奇葩的内置方法 - 零基础入门学习Python014

    字符串:各种奇葩的内置方法 让编程改变世界 Change the world by program 字符串:各种奇葩的内置方法 或许现在又回过头来谈字符串,有些朋友可能会觉得没必要,也有些朋友会觉得不 ...

  6. python 加密模块安装

    我们使用Python做加密算法如AES.MD5.SHA等时,需要用到PyCrypto模块 PyCrypto模块的安装方法 1.一般在官方网站下载: https://www.dlitz.net/soft ...

  7. 让libvirt支持win7运行2核以上

    现在人在部署OpenStack之后会发现按照配额运行Linux的虚拟机没有问题,但是运行windows的虚拟机会发现如果配置2个以上的核则无法识别,windows server也最多支持到4个核.无法 ...

  8. Codeforces 486D D. Valid Sets

    http://codeforces.com/contest/486/problem/D 题意:给定一棵树,点上有权值,以及d,要求有多少种联通块满足最大值减最小值小于等于d. 思路:枚举i作为最大的点 ...

  9. 逻辑数据库设计 - 需要ID(谈主键Id)

    本文的目标就是要确认那些使用了主键,却混淆了主键的本质而造成的一种反模式. 一.确立主键规范 每个了解数据库设计的人都知道,主键对于一张表来说是一个很重要,甚至必需的部分.这确实是事实,主键是好的数据 ...

  10. libusb-win32 在visual studio2008中成功编译回忆录

    关于这个项目不用多说 介绍 libusb是一个针对usb通讯的库. 使用它, 你不需要知道操作系统的细节, 你只需要对USB有足够的了解即可. 它也不需要你写驱动, 所有的工作都可以在用户态完成. 使 ...