配置与舍入模式
用
Decimal.set()(等价于Decimal.config())修改全局默认配置,用Decimal.clone()创建独立配置的构造器。
1. 配置方法
js
Decimal.set({ precision: 5, rounding: 4 }) // 返回 Decimal 构造器本身(可链式)
Decimal.config({ precision: 5 }) // set 的别名,行为相同三个入口:
| 方法 | 作用 |
|---|---|
Decimal.set(config) | 修改默认构造器的配置(推荐写法) |
Decimal.config(config) | 与 set 完全相同(别名) |
Decimal.clone(config?) | 创建新的独立构造器,配置复制自当前构造器;不传参则完全复制 |
js
// 独立构造器示例
const Dec = Decimal.clone({ precision: 9, rounding: 1 });
new Dec(5).div(3) // '1.66666666'(9 位)
new Decimal(5).div(3) // 不受影响,仍按全局配置NOTE
clone出来的构造器实例仍然是Decimal的实例(new Dec(5) instanceof Decimal→true)。- 不同构造器之间可以互相运算(自动转换),结果属于调用方构造器。
- 配置是「进程级全局」的:
set会影响所有由该构造器创建的数字。
2. 配置项总表(默认值实测)
| 配置项 | 类型 | 取值范围 | 默认值 | 说明 |
|---|---|---|---|---|
precision | number | 1 ~ 1e9 | 20 | 计算结果的最大有效数字位数 |
rounding | number | 0 ~ 8 | 4 | 舍入模式(见下表) |
modulo | number | 0 ~ 9 | 1 | 取模模式(见第 4 节) |
toExpNeg | number | 0 ~ -9e15 | -7 | 指数 ≤ 此值时 toString 用科学计数法 |
toExpPos | number | 0 ~ 9e15 | 21 | 指数 ≥ 此值时 toString 用科学计数法 |
minE | number | -1 ~ -9e15 | -9e15 | 低于此指数下溢为 0 |
maxE | number | 1 ~ 9e15 | 9e15 | 高于此指数溢出为 Infinity |
crypto | boolean | true/false | false | random() 是否使用加密安全随机数 |
defaults | boolean | true/false | — | 设为 true 时重置全部配置为默认值 |
js
// 全部配置
Decimal.set({
precision: 50,
rounding: Decimal.ROUND_HALF_EVEN,
modulo: Decimal.EUCLID,
toExpNeg: -10,
toExpPos: 30,
minE: -1e6,
maxE: 1e6,
crypto: true
});
// 一键恢复默认
Decimal.set({ defaults: true });
// 之后:precision=20, rounding=4, toExpNeg=-7, toExpPos=21, modulo=1, crypto=false读取当前配置:直接读静态属性(也可直接赋值):
js
Decimal.precision // 20
Decimal.rounding // 4
Decimal.toExpNeg // -7
Decimal.toExpPos // 21
Decimal.minE // -9000000000000000
Decimal.maxE // 9000000000000000
Decimal.crypto // false
Decimal.modulo // 13. 舍入模式详解(rounding 0–8)
设结果需要截断到第 k 位,比较第 k+1 位:
| 常量 | 值 | 名称 | 行为 | 例:对 2.5 取整 |
|---|---|---|---|---|
ROUND_UP | 0 | 远离零 | 一律向远离 0 的方向进 1 | 3 |
ROUND_DOWN | 1 | 趋向零(截断) | 一律丢弃多余位 | 2 |
ROUND_CEIL | 2 | 向上 | 向 +∞ 进 1 | 3 |
ROUND_FLOOR | 3 | 向下 | 向 -∞ 进 1 | 2 |
ROUND_HALF_UP | 4 | 四舍五入(默认) | 舍入位 ≥5 进 1 | 3 |
ROUND_HALF_DOWN | 5 | 五舍六入 | 舍入位 >5 才进 1 | 2 |
ROUND_HALF_EVEN | 6 | 银行家舍入 | 恰好 .5 时取偶数邻居 | 2 |
ROUND_HALF_CEIL | 7 | 半数向上 | .5 时向 +∞ | 3 |
ROUND_HALF_FLOOR | 8 | 半数向下 | .5 时向 -∞ | 2 |
NOTE
上表「例:对 2.5 取整」为理论值;注意 round() 方法无参数,仅按当前全局 rounding 工作(见 算术运算)。指定模式的舍入请用 toDP(n, mode) / toSD(n, mode) 等(见 格式化与输出)。
验证示例(用 toDP(0, mode) 指定模式对 1.5 / 2.5 取整,实测):
js
new Decimal('1.5').toDP(0, Decimal.ROUND_HALF_UP) // '2'
new Decimal('1.5').toDP(0, Decimal.ROUND_HALF_EVEN) // '2'
new Decimal('2.5').toDP(0, Decimal.ROUND_HALF_EVEN) // '2'(.5 取偶数)
new Decimal('2.5').toDP(0, Decimal.ROUND_HALF_UP) // '3'
new Decimal('2.5').toDP(0, Decimal.ROUND_DOWN) // '2'
new Decimal('-2.5').toDP(0, Decimal.ROUND_CEIL) // '-2'
new Decimal('-2.5').toDP(0, Decimal.ROUND_FLOOR) // '-3'货币场景最常用的两个模式:
js
// 四舍五入(默认):1.005 → 1.01
new Decimal('1.005').toFixed(2) // '1.01'
new Decimal('1.005').toFixed(2, Decimal.ROUND_DOWN) // '1.00'(向下/截断,常用于折扣)4. 取模模式(modulo 0–9)
a mod n 的符号取决于商 q = a / n 如何取整,余数 r = a - n × q。
| 模式 | 值 | 余数符号 | 说明 |
|---|---|---|---|
ROUND_UP | 0 | 与被除数相反 | 较少用 |
ROUND_DOWN | 1 | 与被除数相同 | 默认,等价于 JS 的 % |
ROUND_FLOOR | 3 | 与除数相同 | 等价于 Python 的 % |
ROUND_HALF_EVEN | 6 | — | IEEE 754 的 remainder |
EUCLID | 9 | 恒为非负 | 欧几里得除法,取模运算推荐 |
js
// 默认(modulo=1,同 JS %):余数符号跟随被除数
new Decimal(10).mod(3) // '1'
new Decimal(-10).mod(3) // '-1'
new Decimal(10).mod(-3) // '1'
new Decimal(-10).mod(-3) // '-1'
// 切换为 EUCLID:结果恒非负(-8 mod 3 = 1,8 mod -3 = 2)
Decimal.set({ modulo: Decimal.EUCLID });
new Decimal(-8).mod(3) // '1'
new Decimal(8).mod(-3) // '2'
Decimal.set({ modulo: 1 });5. 指数显示配置示例
js
Decimal.set({ toExpPos: 30 });
new Decimal('1e21').toString() // '1000000000000000000000'(不再是指数形式)
new Decimal('1e30').toString() // '1e+30'
new Decimal('1e31').toString() // '1e+31'
Decimal.set({ toExpNeg: -5 });
new Decimal('1e-7').toString() // '1e-7'
new Decimal('1e-5').toString() // '1e-5'
new Decimal('1e-4').toString() // '0.0001'
Decimal.set({ defaults: true }); // 恢复规则:指数 e >= toExpPos 或 e <= toExpNeg 时使用科学计数法。
6. crypto(加密随机数)
Decimal.set({ crypto: true }) 后,Decimal.random() 使用 crypto.getRandomValues 生成不可预测的随机数(若环境不支持会抛 [DecimalError] crypto unavailable)。详见 数学函数。
7. 配置出错
js
Decimal.set({ precision: 0 }) // 抛错:[DecimalError] Invalid argument: precision: 0
Decimal.set({ precision: 1e9 + 1 }) // 抛错:[DecimalError] Invalid argument: precision: 1000000001TIP
不要把全局配置改来改去:需要不同精度的场景,用 clone() 创建独立构造器,避免污染全局状态(详见 最佳实践与常见坑)。
