做一个用户中奖记录页面,展示每条记录和总金额,遇到浮点数相加出现问题。

Js的浮点数在比较或者做运算的时候会不准确,这个只在初学js的时候读到过概念性的东西,这次就遇到了就在这里记一笔,做一下相关拓展,网上处理的方法也很多,这里摘要一些博主的。

浮点数运算:

转自:https://blog.csdn.net/u013347241/article/details/79210840

思路是将小数转成整数来运算,之后再转回小数。

'use strict'var accAdd = function(num1, num2) {num1 = Number(num1);num2 = Number(num2);var dec1, dec2, times;try { dec1 = countDecimals(num1)+1; } catch (e) { dec1 = 0; }try { dec2 = countDecimals(num2)+1; } catch (e) { dec2 = 0; }times = Math.pow(10, Math.max(dec1, dec2));// var result = (num1 * times + num2 * times) / times;var result = (accMul(num1, times) + accMul(num2, times)) / times;return getCorrectResult("add", num1, num2, result);// return result;
};var accSub = function(num1, num2) {num1 = Number(num1);num2 = Number(num2);var dec1, dec2, times;try { dec1 = countDecimals(num1)+1; } catch (e) { dec1 = 0; }try { dec2 = countDecimals(num2)+1; } catch (e) { dec2 = 0; }times = Math.pow(10, Math.max(dec1, dec2));// var result = Number(((num1 * times - num2 * times) / times);var result = Number((accMul(num1, times) - accMul(num2, times)) / times);return getCorrectResult("sub", num1, num2, result);// return result;
};var accDiv = function(num1, num2) {num1 = Number(num1);num2 = Number(num2);var t1 = 0, t2 = 0, dec1, dec2;try { t1 = countDecimals(num1); } catch (e) { }try { t2 = countDecimals(num2); } catch (e) { }dec1 = convertToInt(num1);dec2 = convertToInt(num2);var result = accMul((dec1 / dec2), Math.pow(10, t2 - t1));return getCorrectResult("div", num1, num2, result);// return result;
};var accMul = function(num1, num2) {num1 = Number(num1);num2 = Number(num2);var times = 0, s1 = num1.toString(), s2 = num2.toString();try { times += countDecimals(s1); } catch (e) { }try { times += countDecimals(s2); } catch (e) { }var result = convertToInt(s1) * convertToInt(s2) / Math.pow(10, times);return getCorrectResult("mul", num1, num2, result);// return result;
};

//计算小数位的长度var countDecimals = function(num) {var len = 0;try {num = Number(num);var str = num.toString().toUpperCase();if (str.split('E').length === 2) { // scientific notationvar isDecimal = false;if (str.split('.').length === 2) {str = str.split('.')[1];if (parseInt(str.split('E')[0]) !== 0) {isDecimal = true;}}let x = str.split('E');if (isDecimal) {len = x[0].length;}len -= parseInt(x[1]);} else if (str.split('.').length === 2) { // decimalif (parseInt(str.split('.')[1]) !== 0) {len = str.split('.')[1].length;}}} catch(e) {throw e;} finally {if (isNaN(len) || len < 0) {len = 0;}return len;}
};//将小数转成整数
var convertToInt = function(num) {num = Number(num);var newNum = num;var times = countDecimals(num);var temp_num = num.toString().toUpperCase();if (temp_num.split('E').length === 2) {newNum = Math.round(num * Math.pow(10, times));} else {newNum = Number(temp_num.replace(".", ""));}return newNum;
};//确认我们的计算结果无误,以防万一
var getCorrectResult = function(type, num1, num2, result) {var temp_result = 0;switch (type) {case "add":temp_result = num1 + num2;break;case "sub":temp_result = num1 - num2;break;case "div":temp_result = num1 / num2;break;case "mul":temp_result = num1 * num2;break;}if (Math.abs(result - temp_result) > 1) {return temp_result;}return result;
};

对金额的处理:

转自: https://www.css88.com/archives/7324

格式化金额:

/*** 将数值四舍五入(保留2位小数)后格式化成金额形式** @param num 数值(Number或者String)* @return 金额格式的字符串,如'1,234,567.45'* @type String*/
function formatCurrency(num) {num = num.toString().replace(/\$|\,/g,'');if(isNaN(num))num = "0";sign = (num == (num = Math.abs(num)));num = Math.floor(num*100+0.50000000001);cents = num%100;num = Math.floor(num/100).toString();if(cents<10)cents = "0" + cents;for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)num = num.substring(0,num.length-(4*i+3))+','+num.substring(num.length-(4*i+3));return (((sign)?'':'-') + num + '.' + cents);
}

或者

function fmoney(s, n) {/** 参数说明:* s:要格式化的数字* n:保留几位小数* */n = n > 0 && n <= 20 ? n : 2;s = parseFloat((s + "").replace(/[^\d\.-]/g, "")).toFixed(n) + "";var l = s.split(".")[0].split("").reverse(),r = s.split(".")[1];t = "";for (i = 0; i < l.length; i++) {t += l[i] + ((i + 1) % 3 == 0 && (i + 1) != l.length ? "," : "");}return t.split("").reverse().join("") + "." + r;
}
//调用
fmoney(9.7,2);//9.70
fmoney('12345.675910', 3);//12,345.676

不过关系到经济利益的时候,还要考虑舍去或者舍入几厘。大家懂的,每个用户几厘钱可能带来巨大的经济收益。

就比如说收手续费,如果一笔手续费计算出来是 3.4521 元,精确到分一般都会收 3.46 元。当然如果是付出去,那可能就是直接舍去了,一般会计算为 3.45 元。

function number_format(number, decimals, dec_point, thousands_sep,roundtag) {/** 参数说明:* number:要格式化的数字* decimals:保留几位小数* dec_point:小数点符号* thousands_sep:千分位符号* roundtag:舍入参数,默认 "ceil" 向上取,"floor"向下取,"round" 四舍五入* */number = (number + '').replace(/[^0-9+-Ee.]/g, '');roundtag = roundtag || "ceil"; //"ceil","floor","round"var n = !isFinite(+number) ? 0 : +number,prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,dec = (typeof dec_point === 'undefined') ? '.' : dec_point,s = '',toFixedFix = function (n, prec) {var k = Math.pow(10, prec);console.log();return '' + parseFloat(Math[roundtag](parseFloat((n * k).toFixed(prec*2))).toFixed(prec*2)) / k;};s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');var re = /(-?\d+)(\d{3})/;while (re.test(s[0])) {s[0] = s[0].replace(re, "$1" + sep + "$2");}if ((s[1] || '').length < prec) {s[1] = s[1] || '';s[1] += new Array(prec - s[1].length + 1).join('0');}return s.join(dec);
}
console.log(number_format(2, 2, ".", ","))//"2.00"
console.log(number_format(3.7, 2, ".", ","))//"3.70"
console.log(number_format(3, 0, ".", ",")) //"3"
console.log(number_format(9.0312, 2, ".", ","))//"9.03"
console.log(number_format(9.00, 2, ".", ","))//"9.00"
console.log(number_format(39.715001, 2, ".", ",", "floor")) //"39.71"
console.log(number_format(9.7, 2, ".", ","))//"9.70"
console.log(number_format(39.7, 2, ".", ","))//"39.70"
console.log(number_format(9.70001, 2, ".", ","))//"9.71"
console.log(number_format(39.70001, 2, ".", ","))//"39.71"
console.log(number_format(9996.03, 2, ".", ","))//"9996.03"
console.log(number_format(1.797, 3, ".", ",", "floor"))//"1.797"

推荐的类库

Numeral.js

一个用于格式化和操作数字的JavaScript库。数字可以被格式化为货币,百分比,时间,几个小数位数,千分位等等。您也可以随时创建自定义格式。

官网及文档:http://numeraljs.com/

GitHub:https://github.com/adamwdraper/Numeral-js

accounting.js

一个轻量级的JavaScript库,用于格式化数字,金额和货币等。

官网及文档:http://openexchangerates.github.io/accounting.js/

GitHub:accounting.js

Math.js

Math.js 是专门为 JavaScript 和 Node.js 提供的一个广泛的数学库。它具有灵活的表达式解析器,支持符号计算,配有大量内置函数和常量,并提供集成解决方案来处理不同的数据类型

像数字,大数字(超出安全数的数字),复数,分数,单位和矩阵。功能强大,易于使用。

官网:http://mathjs.org/

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/

这几个类库帮我们解决很多这类问题,不过通常我们前端做这类运算通常只用于表现层,应用并不是很多。所以很多时候,一个函数能解决的问题不需要引用一个类库来解决。

转载于:https://www.cnblogs.com/yaoyao-sun/p/10274604.html

浮点数运算和金额处理相关推荐

  1. js浮点数运算不精确 如何解决_解决 浏览器处理数字运算时精度丢失的方法

    浏览器处理数字运算时精度丢失的方法 为什么0.1 + 0.2 不等于0.3.因为计算机不能精确表示0.1, 0.2这样的浮点数,计算时使用的是带有舍入误差的数 并不是所有的浮点数在计算机内部都存在舍入 ...

  2. 64位浮点数_JavaScript 浮点数运算的精度问题

    问题描述 在 JavaScript 中整数和浮点数都属于 Number 数据类型,所有数字都是以 64 位浮点数形式储存,即便整数也是如此. 所以我们在打印 1.00 这样的浮点数的结果是 1 而非 ...

  3. 浮点数运算的精度问题:以js语言为例

    在 JavaScript 中整数和浮点数都属于 Number 数据类型,所有数字都是以 64 位浮点数形式储存,即便整数也是如此. 所以我们在打印 1.00 这样的浮点数的结果是 1 而非 1.00  ...

  4. php7的浮点数,php7.1浮点数运算问题

    最近在项目中遇到一个问题,测试服务器接口返回金额精度缺失,导致app解析不正确发生闪退.调试后发现浮点数在json_encode后损失了精度,如下图所示. 网上说是因为php7.1版本的seriali ...

  5. python减法精确度不准是什么问题,聊聊Python中的浮点数运算不准确问题

    大家好,老 Amy 来了.之前就意识到一个问题,但是最近又有朋友提出来了,所以就想着干脆记录下来,分享给大家叭~ 啥问题呢?请看题: 也就是说,需要大家计算1.1-1的值,很多朋友会说:"e ...

  6. PHP浮点数运算精度问题

    最近有客户反应商城订单金额总是不准确,总是相隔一分钱.检查相关代码逻辑都是正确的,就是运用了四则运算.大概推测问题可能出在浮点计算丢失精度.在<PHP程序员雷雪松的博客>中写过一篇关于JS ...

  7. java浮点数误差_浮点数运算的误差

    浮点数运算的误差 在 JavaScript 中整数和浮点数都属于number 数据类型,所有数字都是使用64位浮点数形式储存,遵循IEEE-754双精度标准存储,即便整数也是如此. 所以我们在打印 1 ...

  8. PHP不能精确表达小数 PHP除法结果不准确 php 为什么数字除法不准确 PHP浮点数运算不准确的问题...

    echo intval(0.58*100);//结果为57 echo intval((0.1 + 0.7) * 10);//结果为7 产生这样的原因是计算机内部对部分浮点数不能准确地用二进制表示,就像 ...

  9. Python 浮点数运算

    2019独角兽企业重金招聘Python工程师标准>>> 浮点数用来存储计算机中的小数,与现实世界中的十进制小数不同的是,浮点数通过二进制的形式来表示一个小数.在深入了解浮点数的实现之 ...

  10. python浮点数运算问题_python基础教程之. 浮点数运算:问题和局限

    14. 浮点数运算:问题和局限¶ 浮点数在计算机硬件中表示为以 2 为底(二进制)的小数.例如,十进制小数 0.125 是1/10 + 2/100 + 5/1000 的值,同样二进制小数 0.001 ...

最新文章

  1. [转]什么是CMMI?
  2. 使用mac 终端利用alias设置快捷命令
  3. LeetCode 966. 元音拼写检查器(哈希)
  4. crc16几种标准校验算法及c语言代码
  5. java mybatis 代码生成器_mybatis自动生成java代码
  6. 【JZOJ4743】【NOIP2016提高A组模拟9.2】积木
  7. MySQL:Innodb表 Data free 的计算概要
  8. 如何识别媒体偏见_面部识别技术存在偏见:为什么我们不应该盲目相信新技术
  9. java 状态模式的实现与应用
  10. Resnet 18网络模型
  11. android dns 设置,安卓手机怎么设置DNS Android手机修改DNS图文教程
  12. android 自动跳转市场,js判断设备,跳转app应用、android市场或者AppStore
  13. qt 雷达扫描障碍物_激光雷达Lidar与毫米波雷达Radar:自动驾驶的利弊
  14. SpingMVC文件下载,ie浏览器提示无法打开该Internet站点.请求的站点不可用,或找不到.请以后再试.
  15. 求大神指导,海康威视服务器装系统装到这一步装不走了,怎么搞
  16. html表格一行设置颜色,更改表格中一行的颜色,html
  17. Linux 进程管理之current
  18. unity 位移贴图正弦波面
  19. Docker: 容器与镜像
  20. 小球下落 DroppingBalls

热门文章

  1. 返回值由hresult变为void型_java高级之泛型
  2. 敏捷开发之组织级经验分享
  3. 2012.4.16总结(二)
  4. 剑指offer最新版_剑指offer第二版速查表
  5. MCU——TC04B触摸按键芯片驱动
  6. php 修改服务器ip,php 修改服务器ip
  7. spark入门及环境搭建
  8. opencv 缺少boostdesc_bgm.i等文件
  9. 笔记本如何查看mac地址
  10. ActiveMQ消息队列介绍(转)