在做项目时,需要页面进行数据计算,简单的加法,对JavaScript来说就会出现错误了,例如alert(0.3-(0.5-0.1));结果不是-0.1而是-0.1
在 JavaScript 中整数和浮点数都属于 Number 数据类型,所有数字都是以 64 位浮点数形式储存,即便整数也是如此。 所以我们在打印 1.00 这样的浮点数的结果是 1 而非 1.00 。
JavaScript 里的数字是采用 IEEE 754 标准 的 64 位双精度浮点数。该规范定义了浮点数的格式,对于64位的浮点数在内存中的表示,最高的1位是符号位,接着的11位是指数,剩下的52位为有效数字,具体:
- 第0位:符号位, s 表示 ,0表示正数,1表示负数;
- 第1位到第11位:储存指数部分, e 表示 ;
- 第12位到第63位:储存小数部分(即有效数字),f 表示,
解决方案:
使用 浮点数运算 toFixed() 方法;
自定义函数方法:
加法函数
JavaScript 代码:
- /**
- ** 加法函数,用来得到精确的加法结果
- ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
- ** 调用:accAdd(arg1,arg2)
- ** 返回值:arg1加上arg2的精确结果
- **/
- function accAdd(arg1, arg2) {
- var r1, r2, m, c;
- try {
- r1 = arg1.toString().split(".")[1].length;
- }
- catch (e) {
- r1 = 0;
- }
- try {
- r2 = arg2.toString().split(".")[1].length;
- }
- catch (e) {
- r2 = 0;
- }
- c = Math.abs(r1 - r2);
- m = Math.pow(10, Math.max(r1, r2));
- if (c > 0) {
- var cm = Math.pow(10, c);
- if (r1 > r2) {
- arg1 = Number(arg1.toString().replace(".", ""));
- arg2 = Number(arg2.toString().replace(".", "")) * cm;
- } else {
- arg1 = Number(arg1.toString().replace(".", "")) * cm;
- arg2 = Number(arg2.toString().replace(".", ""));
- }
- } else {
- arg1 = Number(arg1.toString().replace(".", ""));
- arg2 = Number(arg2.toString().replace(".", ""));
- }
- return (arg1 + arg2) / m;
- }
- //给Number类型增加一个add方法,调用起来更加方便。
- Number.prototype.add = function (arg) {
- return accAdd(arg, this);
- };
减法函数
JavaScript 代码:
- /**
- ** 减法函数,用来得到精确的减法结果
- ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
- ** 调用:accSub(arg1,arg2)
- ** 返回值:arg1加上arg2的精确结果
- **/
- function accSub(arg1, arg2) {
- var r1, r2, m, n;
- 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)); //last modify by deeka //动态控制精度长度
- n = (r1 >= r2) ? r1 : r2;
- return ((arg1 * m - arg2 * m) / m).toFixed(n);
- }
- // 给Number类型增加一个mul方法,调用起来更加方便。
- Number.prototype.sub = function (arg) {
- return accMul(arg, this);
- };
乘法函数
JavaScript 代码:
- /**
- ** 乘法函数,用来得到精确的乘法结果
- ** 说明: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 代码:
- /**
- ** 除法函数,用来得到精确的除法结果
- ** 说明: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);
- };
Math.js
GitHub:https://github.com/josdejong/mathjs
decimal.js
为 JavaScript 提供十进制类型的任意精度数值。
官网:http://mikemcl.github.io/decimal.js/
GitHub:https://github.com/MikeMcl/decimal.js
big.js
官网:http://mikemcl.github.io/big.js
GitHub:https://github.com/MikeMcl/big.js/