解决前端精度问题的JS库-math.js

21,455 阅读2分钟

由于现在开发的软件都是零售、餐饮这方面的项目居多,自然就会对金额计算这块要求就会比较高。而js对精度这块计算一直存在缺陷,所以给大家推荐一个类库-math.js

JS的加减乘除算

1、加法算术:0.1+0.2

	console.log(0.1+0.2);
	结果是:0.30000000000000004

2、减法算术:0.8-0.7

	console.log(0.8-0.7)
	结果是:0.10000000000000009

3、乘法算术:5.10*100

	console.log(5.10*100)
	结果是:509.99999999999994

4、除法法算术 6.10/0.1

	console.log(6.10/0.1)
	结果是:60.99999999999999

JavaScript 浮点数运算结果不对,是因为浮点数的存储问题导致计算结果不对。

Math.js

Math.js是一个用于JavaScript和Node.js的扩展数学库。它具有支持符号计算的灵活表达式解析器,大量内置函数和常量,并提供了集成的解决方案来处理不同的数据类型,例如数字,大数,复数,分数,单位和矩阵,强大且易于使用。

特征

  • 支持数字,大数,复数,分数,单位,字符串,数组和矩阵。
  • 与JavaScript的内置Math库兼容,Math用法,一样,门槛低
  • 包含一个灵活的表达式解析器。
  • 进行符号计算。
  • 带有大量内置函数和常量。
  • 也可以用作命令行应用程序。
  • 在任何JavaScript引擎上运行。
  • 很容易扩展。
  • 开源。

帮助使用教程:

1、传统使用,引入math.js
    <!DOCTYPE HTML>
    <html>
    <head>
      <script src="https://unpkg.com/mathjs@7.0.1/dist/math.min.js" type="text/javascript"></script>
    </head>
    <body>
      <script type="text/javascript">
        const ans = math.add(0.1, 0.2)     //  0.30000000000000004
        console.log(math.format(ans, {precision: 14})) // '0.3'
        console.log(math.sqrt(4).toString()) // 2
      </script>
    </body>
    </html>
2、es module

npm安装

	npm install mathjs

使用

import { create, all } from 'mathjs'
const config = { 
  number: 'BigNumber',
  precision: 20
}
const math = create(all, config);
export default {
  methods: {
  	//开方
    numberSqrt: function(arg1){
    	return math math.sqrt(arg1)
    },
    //除
    numberExcept: function (arg1, arg2) {
      return math.divide(arg1, arg2);
    },
    //乘
    numberRide: function (arg1, arg2) {      
      return math.multiply(arg1, arg2);
    },
    //加
    numberAdd:function (arg1,arg2) {
    return math.add(arg1, arg2);
    }
    //减
    numberSub:function (arg1,arg2) {
    return math.add(arg1, -arg2);
    }
  }
}

math.js 常用数学功能

<script type="text/javascript">
    // expressions
    console.log(math.evaluate('1.2 * (2 + 4.5)')) // 7.8
    console.log(math.evaluate('12.7 cm to inch')) // 5 inch
    console.log(math.evaluate('sin(45 deg) ^ 2')) // 0.5
    console.log(math.evaluate('9 / 3 + 2i')) // 3 + 2i
    console.log(math.evaluate('det([-1, 2; 3, 1])')) // -7
    
    // mixed use of different data types in functions
    console.log(math.add(5, [9, 6])) // number + Array, [14, 11]
    console.log(math.multiply(math.unit('5 mm'), 3)) // Unit * number,  15 mm
    console.log(math.subtract([2, 3, 4], 10)) // Array - number, [-8, -7, -6]
    console.log(math.add(math.matrix([4, 1]), [2, 9])) // Matrix + Array, [6, 10]	
    
    // chain operator
    console.log(math.chain(3)
        .add(4)
        .subtract(2)
        .done()) // 5

	console.log(math.chain( [[1, 2], [3, 4]] )
        .subset(math.index(0, 0), 8)
        .multiply(3)
        .done()) // [[24, 6], [9, 12]]
</script>