数字 #
Math.js 支持三种类型的数字
- Number,用于快速浮点数算术,在本页介绍。
- BigNumber,用于任意精度算术,在 BigNumbers 页面介绍。
- Fraction,将数字存储为分子和分母的形式,在 Fractions 页面介绍。
配置 #
大多数函数可以根据输入类型确定输出类型:输入为 Number 时返回 Number,输入为 BigNumber 时返回 BigNumber。无法根据输入确定输出类型的函数(例如 math.evaluate)使用默认的 Number 类型,这可以在实例化 math.js 时进行配置。
math.config({
number: 'number' // Default type of number:
// 'number' (default), 'BigNumber', or 'Fraction'
})
舍入误差 #
Math.js 使用内置的 JavaScript Number 类型。Number 是一个浮点数,精度有限,为 64 位,约 16 位数字。JavaScript Number 可以表示的最大整数是 +/- 9007199254740992(+/- 2^53)。由于浮点数精度的限制,计算过程中可能会发生舍入误差。这很容易演示。
// a round-off error
0.1 + 0.2 // 0.30000000000000004
math.add(0.1, 0.2) // 0.30000000000000004
在大多数情况下,舍入误差并不重要:它们对结果没有显著影响。然而,在显示输出给用户时,这看起来很难看。一种解决方案是在显示的输出中将精度限制在实际 16 位精度之下。
// prevent round-off errors showing up in output
const ans = math.add(0.1, 0.2) // 0.30000000000000004
math.format(ans, {precision: 14}) // '0.3'
替代方案是使用 Fractions(以分子和分母形式存储数字),BigNumbers(存储更高精度的数字),或者 bigint(可以存储更大的整数)。
最小值和最大值 #
Number 可以存储的值在 5e-324 和 1.7976931348623157e+308 之间。小于最小值的值存储为 0,大于最大值的值存储为 +/- Infinity。
// exceeding the maximum and minimum number
console.log(1e309) // Infinity
console.log(1e-324) // 0
相等性 #
由于计算中的舍入误差,比较 JavaScript Number 是不安全的。例如,在 JavaScript 中执行 0.1 + 0.2 == 0.3 将返回 false,因为加法 0.1 + 0.2 会产生舍入误差,并且不精确等于 0.3。
为了解决这个问题,math.js 的关系函数会检查比较值之间的相对和绝对差是否小于配置选项 relTol 和 absTol。伪代码如下(不考虑 0、Infinity 和 NaN 的特殊情况):
abs(a-b) <= max(relTol * max(abs(a), abs(b)), absTol)
其中
relTol是 x 和 y 之间的相对容差,absTol是绝对容差。相对容差和绝对容差是可配置的,默认值分别为1e-12和1e-15。请参阅 配置。DBL_EPSILON是最小的正浮点数,使得1.0 + DBL_EPSILON !== 1.0。这是一个常量,其值大约为2.2204460492503130808472633361816e-16。
请注意,关系函数不能用于比较非常小的值(< 2.22e-16)。这些值都将被视为零。
示例
// compare values having a round-off error
console.log(0.1 + 0.2 === 0.3) // false
console.log(math.equal(0.1 + 0.2, 0.3)) // true
// small values (< 2.22e-16) cannot be compared
console.log(3e-20 === 3.1e-20) // false
console.log(math.equal(3e-20, 3.1e-20)) // true
可用的关系函数有:compare、equal、larger、largerEq、smaller、smallerEq、unequal。