数学神器:Math.js,JavaScript和Node.js的最佳数学库

发表时间: 2023-12-16 06:31

家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。

什么是 Math.js

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

Math.js 适用于任何兼容 ES6 的 JavaScript 引擎,包括 Node.js、Chrome、Firefox、Safari 和 Edge。Math.js 的典型特征包括:

  • 支持数字、大数字、复数、分数、单位、字符串、数组和矩阵。
  • 与 JavaScript 的内置数学库兼容。
  • 包含灵活的表达式解析器。
  • 支持符号计算。
  • 带有大量内置函数和常量。
  • 可以用作命令行应用程序。
  • 可在任何 JavaScript 引擎上运行。
  • 易于扩展且完全开源。

目前 Math.js 在 Github 通过 MIT 协议开源,有超过 13.7k 的 star、1.3k 的 fork、项目依赖量 63.8k、代码贡献者 200+、妥妥的前端优质开源项目

为什么需要 Math.js

实际上,Math.js 试图实现的是提供一个环境,开发者可以在其中使用混合数据类型(Mixed Data Types)进行计算,例如:将常规数字与复数或 BigNumber 相乘,并处理矩阵中的所有数据。 Math.js 还允许轻松添加新的数据类型,例如 BigInt。

Math.js 使用的解决方案有两个核心组成部分:

  • 类型化函数(Typed functions): 所有函数都使用 typed-function 创建,从而使得使用新数据类型动态创建和扩展单个函数、自动对函数输入进行类型转换等变得更加容易。因此,如果要为两个数字创建乘法函数,则可以通过支持两个 BigInt 相乘来扩展 。 如果定义从 BigInt 到数字的转换,typed-function 自动允许将 BigInt 与数字相乘。
import typed from 'typed-function'// 创建 typed-function 函数var fn1 = typed({  'number, string': function (a, b) {    return 'a is a number, b is a string';  }});// 创建每个参数具有多种类型的类型化函数(类型联合)var fn2 = typed({  'string, number | boolean': function (a, b) {    return 'a is a string, b is a number or a boolean';  }});// 使用任何类型参数创建类型化函数var fn3 = typed({  'string, any': function (a, b) {    return 'a is a string, b can be anything';  }});
  • 依赖注入(Dependency injection): 当有一个支持 BigInt 的 multiply 函数时,由于依赖注入,其他在底层使用 multiply 的函数也将自动支持 BigInt, 反之亦然。如果不需要太重的 multiply(支持 BigNumbers、矩阵等),并且只需要简单的数字支持,则可以使用仅用于数字的轻量级 multiply 实现, 并将其注入到 prod 和其他函数中。

在最底层,mathjs 具有创建不可变(immutable)函数的不可变工厂函数。 核心函数 math.create(...) 用于创建一个新实例,其中包含从所有传递的工厂函数创建的函数, mathjs 实例是创建的函数的集合。 其包含一个像 math.import 这样的函数,允许使用新函数扩展实例,然后可以在表达式解析器中使用。

注意:typed-function 库以灵活、有组织的方式将类型检查逻辑和类型转换移到函数之外。如果输入参数错误,则自动抛出信息错误。

如何使用 Math.js

Math.js 可以在 Node.js 和浏览器环境中使用,使用方式与 JavaScript 的内置 Math 库类似。除此之外,math.js 可以计算表达式并支持链式操作。

// 函数和常量math.round(math.e, 3); // 2.718math.atan2(3, -3) / math.pi; // 0.75math.log(10000, 10); // 4math.sqrt(-4); // 2imath.pow(  [    [-1, 2],    [3, 1],  ],  2); // [[7, 0], [0, 7]]// 表达式math.evaluate('12 / (2.3 + 0.7)'); // 4math.evaluate('12.7 cm to inch'); // 5 inchmath.evaluate('sin(45 deg) ^ 2'); // 0.5math.evaluate('9 / 3 + 2i'); // 3 + 2imath.evaluate('det([-1, 2; 3, 1])'); // -7// 链式操作math.chain(3).add(4).multiply(2).done(); // 14

参考资料

https://github.com/josdejong/mathjs

https://mathjs.org/

https://github.com/josdejong/mathjs

https://github.com/josdejong/typed-function/

https://www.webappers.com/2014/09/23/math-js-awesome-math-library-javascript-node-js/