最近在做订单相关的一个功能,涉及到金额的计算,有人建议,将计算全部抛给后端来做吧,前端就不需要再维护一套算法了,话说的在理,但是呢,想想用户体验,单价*数量=金额,当用户改变一个数量时,用户都口算出来金额了,然而页面还在请求的loading中,这也太.......

于是乎,我决定前端也维护一套算法,给用户最快的响应.页面大致如下:

正常来说,这完全不是个事,很快就全部按要求实现 了,然而,测试过程中,发现了下图:

什么?    0.14*100=14.0000000000000002     ???

开发这么多年,真的第一次遇到,于是乎开始了各种测试,各种查阅,原来是这样啊:
js计算时,会将十进制转换成二进制,再进行计算,但有些小数转换成二进制时候,出现了无限循环,由于位数有限,所以就出现了截取,所以就导致了再转化成十进制后结果的不精确.所以就出现了: 0.1+0.2 !== 0.3

不说这些废话了,直接来解决方案:

math.js 是一款功能强大,使用灵活的数学库。不过此处我只需使用加减乘除等简单的方法,需要更多者可以查阅官网

1,引入第三方的js库, math.js,

官网:http://mathjs.org/

math.js的下载地址是:
https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.0.0/math.js。

2,在程序入口处统一配置以下math.js,

 //统一配置math.js
math.config({
number: 'BigNumber',
// 'number' (default),
precision: 20
});

3,使用mathjs里的运算方式改写计算公式:比如,以前的的金额计算如下:

  item.amount = item.listPrice * item.orderNum;

改写之后为:

 //使用math.js转换数据类型
item.listPrice = math.bignumber(item.listPrice) ; //计算金额:金额=列表价*数量
var amountOfBigNumber = item.listPrice * item.orderNum; //转换结果类型,提取数字(不转的话,得到的是对象)
item.amount = math.number(amountOfBigNumber);

这样就不会出现误差,结果就能正常了,即  0.14 * 100 = 14 !

注:常用的几个运算方法是:

运算 方法名 参数 备注
math.add(a,b,c,...)
参数个数>=2 得到几个数字的和
math.subtract(a,b)
参数个数=2 得到 a-b 的结果, 不可连减
math.multiply(a,b,c,...) 参数个数>=2 得几个参数的乘积
math.divide(a,b)
参数个数=2 得到 a/b 的结果 ,不可连除
转换为bigNumber类型
math.bignumber(a)
  浮点数,进行运算时,转换成bigNumber才能保证得到精确的结果
转换为数字类型
math.number(a)
  bignumber为对象,此方法可以获取对象中的数字部分

另外,还有以款比较强大的数学库,BigNumber.js,同样能解决我们的问题,有兴趣者可以研究下

js计算结果不精确问题解决--math.js的使用的更多相关文章

  1. js 计算快速统计中用到的日期

    前言 最近在做统计报表模块,其中查询条件用到了快速查询,主要为了方便客户统计查询常用的几个日期纬度,比如本周.上周.本月.上月.昨日. 使用js计算,主要用到了js Date. getDate().g ...

  2. 使用math.js进行javascript精确计算

    javascript进行浮点运算会有尾差,比如算个0.1+0.7试试,得到的不是0.8 .这个问题可以使用math.js解决. Math.js是一款开源的JavaScript和Node.js数学库,用 ...

  3. js 数值精确运算使用math.js

    javaScript 浮点数运算的精度问题 问题:编程中你可能会遇到0.1*7=0.7000000000000001; 原因:几乎所有的编程语言都采用了 IEEE-745 浮点数表示法,任何使用二进制 ...

  4. js计算2个日期相差的天数,两个日期相差的天数,日期相隔天数

    js计算2个日期相差的天数,两个日期相差的天数,日期相隔天数 >>>>>>>>>>>>>>>>>& ...

  5. js计算日期相差的天数

    在网站开发中,经常会遇到计算日期相差的天数,js 没有提供相应的方法,所以自己写一个,方便将来查看: 代码: function DateDiff(sDate1, sDate2, splitStr) { ...

  6. mathjs,math.js解决js运算精度问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. js计算两个日期的天数差值

    js计算两个日期的天数差值 通过两个日期计算这两个日期之间的天数差值 /** * 计算天数差的函数,通用 * @param sDate1 * @param sDate2 * @returns {Num ...

  8. JS计算距当前时间的时间差

    /** * JS获取距当前时间差 * * @param int time JS毫秒时间戳 * */ function get_time_diff(time) { var diff = ''; var ...

  9. JS计算两个日期之间的天数

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. Serlvet开发

    javaweb学习总结(五)——Servlet开发(一) 一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口 ...

  2. Shell脚本实现对文件编辑

    常见Linux文件的编辑命令 vi/vim,有时候我们想写一个脚本实现对文件编辑,这个时候,可能就不够用了,下面介绍一些办法 1.echo命令 Shell的echo命令常用于字符串的输出 例如: [r ...

  3. rust变量与可变性

    fn main() { //let x = 5; let mut x = 5; //通过const定义常量名称要大写,并且值不可更改 const Y:i32=6; println!("Y i ...

  4. 第10组 Beta冲刺(3/5)

    链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 新增修改用户信息.任务完成反馈等功能API 服务器后端部署,API接口的bet ...

  5. python-使用阿里云镜像加速

    1. 在当前用户根目录下建立.pip文件夹 mkdir ~/.pip2.在.pip文件夹下创建文件pip.conf,并追加内容 [global]trusted-host=mirrors.aliyun. ...

  6. 如何解决“HttpException (0x80004005): 超过了最大请求长度”问题

    .net mvc项目在做上传文件时,出现这个问题,上传文件的是通过表单提交,后台是通过请求里面获取文件信息的 1.问题截图: 堆栈信息 “/”应用程序中的服务器错误.超过了最大请求长度.说明: 执行当 ...

  7. js控制input框只能输入数字和一位小数点和小数点后面两位小数

    <script language="JavaScript" type="text/javascript"> function clearNoNum( ...

  8. JS执行——Promise

    https://www.jianshu.com/p/b16e7c9e1f9f Promise Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理且更强大.它最早由社 ...

  9. openresty开发系列37--nginx-lua-redis实现访问频率控制

    openresty开发系列37--nginx-lua-redis实现访问频率控制 一)需求背景 在高并发场景下为了防止某个访问ip访问的频率过高,有时候会需要控制用户的访问频次在openresty中, ...

  10. WebGL调试工具分享

    学习WebGL,我们需要一些好用的调试工具,下面分享3个常用的调试工具. WebGL Inspector 下载地址:https://github.com/benvanik/WebGL-Inspecto ...