🙏废话不多说系列,直接开整🙏
业务背景:有时候需要前端实时计算出高精度的数据用来快速给客户显示。
这里本文介绍常见的四种方式供大家参考学习:
- math.js
- bignumber.js
- decimal.js
- big.js
这 4 种都是可以满足前端高精度计算的需求的,大家不妨根据自己的实际情况使用。
一、mathJS
官网地址:math.js | an extensive math library for JavaScript and Node.js (mathjs.org)
(1)使用示例
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="math.js | basic usage">
<title>math.js | basic usage</title>
<!-- CDN 实现高精度计算 -->
<!-- 在线 HTML 编辑器地址:https://jsbin.com/devacu/edit?html,output -->
<script src="https://unpkg.com/mathjs/lib/browser/math.js"></script>
</head>
<body>
<script>
// basic usage of math.js
//
// website: http://mathjs.org
// docs: http://mathjs.org/docs
// examples: http://mathjs.org/examples
// functions and constants
print(math.round(math.e, 3)); // 2.718
print(math.atan2(3, -3) / math.pi); // 0.75
print(math.log(10000, 10)); // 4
print(math.sqrt(-4)); // 2i
print(math.pow([[-1, 2], [3, 1]], 2)); // [[7, 0], [0, 7]]
print(math.derivative('x^2 + x', 'x')); // 2 * x + 1
// expressions
print(math.evaluate('12 / (2.3 + 0.7)')); // 4
print(math.evaluate('12.7 cm to inch')); // 5 inch
print(math.evaluate('9 / 3 + 2i')); // 3 + 2i
print(math.evaluate('det([-1, 2; 3, 1])')); // -7
print(math.evaluate('10 / 3')); // 3.3333333333333
print(math.evaluate('1 - 0.9')); // 0.1
print(math.evaluate('1 - 0.9 * (23 / 2)')); // -9.35
// chaining
var a = math.chain(3)
.add(4)
.multiply(2)
.done();
print(a); // 14
// helper function to output formatted results.
function print(value) {
var precision = 14;
document.write(math.format(value, precision) + '<br>');
}
</script>
</body>
</html>
(2)结果展示
2.718
0.75
4
2i
[[7, 0], [0, 7]]
2 * x + 1
4
5 inch
3 + 2i
-7
3.3333333333333
0.1
-9.35
14
二、bignemberJS
官网地址:GitHub - MikeMcl/decimal.js: An arbitrary-precision Decimal type for JavaScript
(1)使用示例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>JavaScript 精确计算 - bignemberJS</title>
<title>Bignumber.js CDN Example</title>
<!-- 引入 bignumber.js CDN -->
<script src="https://cdn.jsdelivr.net/npm/bignumber.js@latest/bignumber.min.js"></script>
</head>
<body>
<h1>Bignumber.js CDN 示例</h1>
<p>计算结果将显示在这里:</p>
<div id="result"></div>
<!-- 你的脚本 -->
<script>
// 使用 bignumber.js 进行计算
let result = new BigNumber(0.1).plus(0.2).toString();
// 将结果显示在页面上
document.getElementById('result').innerText = '0.1 + 0.2 = ' + result;
// 你可以添加更多的计算示例
let result2 = new BigNumber(123.456).times(100).toString();
document.getElementById('result').innerHTML += '<br>123.456 * 100 = ' + result2;
let result3 = new BigNumber(335).div(6).dp(3).toString();
document.getElementById('result').innerHTML += '<br>335 / 6 = ' + result3;
// 1. 计算 0.1 + 0.2
let result4 = new BigNumber(0.1).plus(0.2).toString();
console.log('0.1 + 0.2 =', result4); // 输出: 0.3
// 2. 计算 123.456 乘以 100
let result5 = new BigNumber(123.456).times(100).toString();
console.log('123.456 * 100 =', result5); // 输出: 12345.6
// 3. 计算 335 除以 6,并保留 3 位小数
let result6 = new BigNumber(335).div(6).dp(3).toString();
console.log('335 / 6 =', result6); // 输出: 55.833
// 也可以直接使用字符串来避免精度问题
let result7 = new BigNumber('0.1').plus('0.2').toString();
console.log('0.1 (string) + 0.2 (string) =', result7); // 输出: 0.3
</script>
</body>
</html>
(2)结果展示
0.1 + 0.2 = 0.3
123.456 * 100 = 12345.6
335 / 6 = 55.833
0.1 (string) + 0.2 (string) = 0.3
(3)注意事项
- 在使用 bignumber.js 时,尽量使用字符串来初始化
BigNumber对象,特别是当数字非常大或精度非常高时。这是因为直接使用数字字面量可能会导致 JavaScript 在解析时就丢失精度。 dp方法用于设置小数点后的位数,并返回一个新的BigNumber对象。如果你需要将其转换为字符串或其他类型,可以使用toString()方法。- bignumber.js 提供了丰富的 API,包括加法、减法、乘法、除法、指数运算、开平方等,可以满足大多数高精度计算的需求。
三、decimalJS
这里为了快速使用 decimal.js 进行计算演示,使用 CDN :
(1)使用示例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>JavaScript 精确计算 - decimalJS</title>
<!-- CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/decimal.js/10.3.1/decimal.min.js"></script>
</head>
<body>
<script>
// 使用 Decimal 构造函数创建一个 Decimal 类型的实例
let a = new Decimal(0.1);
let b = new Decimal(0.2);
// 加法
let sum = a.plus(b); // 0.3
console.log("和:", sum.toString());
// 减法
let diff = a.minus(b); // -0.1
console.log("差:", diff.toString())
// 乘法
let product = a.times(b); // 0.02
console.log("积:", product.toString())
// 除法
let quotient = a.dividedBy(b); // 0.5
console.log("除:", quotient.toString())
// 也可以链式调用
let result = new Decimal(10).times(3).plus(2).dividedBy(4); // 8
console.log("综合调用:", result.toString())
Decimal.set({ precision: 5 })
let rounded = new Decimal(1).div(3); // 0.33333
console.log("设置计算精度有效位数:", rounded.toString())
</script>
</body>
</html>
(2)结果展示
和: 0.3
差: -0.1
积: 0.02
除: 0.5
综合调用: 8
设置计算精度有效位数: 0.33333
(3)注意事项
- 当你使用
decimal.js时,应该总是通过Decimal构造函数来创建新的Decimal实例,而不是直接使用 JavaScript 原生的数字类型进行运算。 decimal.js提供的 API 大多是以方法的形式存在的,比如plus(),minus(),times(),dividedBy()等,这有助于避免原生 JavaScript 中的精度问题。decimal.js还支持比较、四舍五入、开方、对数等更多高级数学功能。
通过使用 decimal.js,你可以在 JavaScript 中进行高精度的数学计算,而不必担心浮点数运算中常见的精度问题。
四、bigJS
(1)使用示例
// CDN 引入方式一
<script src="https://cdn.jsdelivr.net/npm/big.js@6.0.0/big.min.js" type="text/javascript" charset="utf-8"></script>
// CDN引入方式二
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/big.js/6.0.3/big.min.js" type="application/javascript"></script>
(2)完整代码展示
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/big.js/6.0.3/big.min.js"
type="application/javascript"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/big.js@6.0.0/big.min.js" type="text/javascript" charset="utf-8"></script> -->
</head>
<body>
<hr>
</body>
<script>
/**
* 加法:四舍五入保留4位有效数据
*/
function func_add(a = 0, b = 0, scale = 4) {
return new Big(a).add(b).toFixed(scale);
}
/**
* 减法:四舍五入保留4位有效数据
*/
function func_sub(a, b, scale = 4) {
return new Big(a).sub(b).toFixed(scale)
}
/**
* 乘法:四舍五入保留4位有效数据
*/
function func_mul(a = 0, b = 0, scale = 4) {
return new Big(a).mul(b).toFixed(scale);
}
/**
* 除法:四舍五入保留4位有效数据
*/
function func_div(a, b, scale = 4) {
try {
return new Big(a).div(b).toFixed(scale);
} catch (e) {
//TODO handle the exception
// console.error(e)
return new Big(0).toFixed(scale)
}
}
function func_math() {
Big.DP = 10
Big.RM = 1
x = new Big(2);
y = new Big(3);
z = x.div(y) // "0.6666666667"
z1 = z.sqrt() // "0.8164965809"
z2 = z.pow(-3) // "3.3749999995"
z3 = z.times(z) // "0.44444444448888888889"
z4 = z.times(z).round(10) // "0.4444444445"
console.log(z1.toFixed(10), z2.toFixed(10), z3.toFixed(10), z4.toFixed(10));
}
function fun_initBigDemo() {
var x = new Big(255.5)
console.log("位数补齐(指定有效位数为5位):", x.toFixed(5)); // 255.50000
console.log("科学技术法:", x.toExponential(5)); // 2.55500e+2
console.log("有效位数:", x.toPrecision(5)); // 255.50
console.log("定义大数据:", x); // 全部数据结构
console.log("高精度加法:", func_add(0.111, 0.2122235));
console.log("高精度减法:", func_sub(1, 0.9, 4));
console.log("高精度乘法:", func_mul(0.3333, 0.2222222, 6));
console.log("高精度除法:", func_div(10, 3, 4), func_div(10, 0));
}
// fun_initBigDemo(); // 初始化执行此函数
func_math();
</script>
</html>
附录
- math.js 工具类官网地址:math.js | an extensive math library for JavaScript and Node.js (mathjs.org)
- bignumber.js GitHub地址:GitHub - MikeMcl/decimal.js: An arbitrary-precision Decimal type for JavaScript
- big.js GitHub地址:GitHub - favio41/big-js: A small, fast JavaScript library for arbitrary-precision decimal arithmetic.
- CDN
🙏至此,非常感谢阅读🙏