格式化与输出
格式化方法分两类:
- 返回字符串:
toString/valueOf/toJSON/toFixed/toExponential/toPrecision/toBinary/toOctal/toHex- 返回 Decimal:
toDP/toSD/toNearest/toFraction(返回 Decimal 数组)- 返回 number:
toNumber
1. 基础转换:toString / valueOf / toJSON / toNumber
| 方法 | 返回类型 | 说明 |
|---|---|---|
toString() | string | 十进制字符串;按 toExpNeg/toExpPos 决定是否科学计数法;-0 → '0' |
valueOf() | string | 同 toString(),但 -0 → '-0' |
toJSON() | string | 同 toString(),供 JSON.stringify 使用 |
toNumber() | number | 转原生 Number(可能丢失精度/溢出为 Infinity) |
js
new Decimal('1.5').toString() // '1.5'
new Decimal('-0').toString() // '0'
new Decimal('-0').valueOf() // '-0'(唯一能区分 -0 的字符串形式)
JSON.stringify({ price: new Decimal('19.99') })
// '{"price":"19.99"}'(自动调用 toJSON,不丢精度)
new Decimal('1.5').toNumber() // 1.5
new Decimal('1e400').toNumber() // Infinity(超出 Number 范围)NOTE
valueOf 返回字符串而非数字,正是为了保证精度。这也意味着 x + 1 会变成字符串拼接 '1.51',不要直接对 Decimal 用算术运算符。
2. 指定小数位 / 有效数字(返回字符串)
toFixed(decimalPlaces?, rounding?)
固定小数位数,不足补 0,返回字符串。decimalPlaces 范围 0 ~ 1e9。
js
new Decimal('255.5').toFixed(5) // '255.50000'(补零)
new Decimal('255.5').toFixed() // '255.5'(无参数:完整展开,不使用科学计数法)
new Decimal('1.005').toFixed(2) // '1.01'
new Decimal('1.005').toFixed(2, Decimal.ROUND_DOWN) // '1.00'(指定舍入模式)
new Decimal('0.0000001').toFixed() // '0.0000001'(避免科学计数法的常用手段)负数与负零:
js
new Decimal('-0.5').toFixed(0) // '-1'(HALF_UP 远离零)
new Decimal('-1.5').toFixed(0) // '-2'
new Decimal('-0').toFixed(2) // '0.00'(负零不显示负号)toExponential(decimalPlaces?, rounding?)
科学计数法,decimalPlaces 为小数点后位数:
js
new Decimal('255.5').toExponential(5) // '2.55500e+2'
new Decimal('255.5').toExponential() // '2.555e+2'(默认:精确表示所需位数)
new Decimal('-0').toExponential(2) // '0.00e+0'toPrecision(significantDigits?, rounding?)
按有效数字位数输出(与精度概念一致):
js
new Decimal('255.5').toPrecision(5) // '255.50'
new Decimal('255.5').toPrecision(2) // '2.6e+2'(位数不够时用科学计数法)
new Decimal('0.000123456').toPrecision(6) // '0.000123456'3. 指定小数位 / 有效数字(返回 Decimal)
toDP(decimalPlaces?, rounding?)(别名 toDecimalPlaces)
按小数位舍入,返回 Decimal(可继续运算):
js
new Decimal('1.235').toDP(2) // '1.24'
new Decimal('1.235').toDP(2, Decimal.ROUND_HALF_DOWN) // '1.23'
new Decimal('1.5').toDP(0, Decimal.ROUND_HALF_EVEN) // '2'
new Decimal('2.5').toDP(0, Decimal.ROUND_HALF_EVEN) // '2'(银行家舍入)
// 链式:舍入后继续计算
new Decimal('1.23456').toDP(2).times(100) // '123'WARNING
toDP 的 decimalPlaces 不允许负数:new Decimal('1234.5').toDP(-1) 抛 [DecimalError] Invalid argument: -1(与 bignumber.js 不同)。
toSD(significantDigits?, rounding?)(别名 toSignificantDigits)
按有效数字舍入,返回 Decimal:
js
new Decimal('1.235').toSD(3) // '1.24'
new Decimal('1234.5').toSD(3) // '1230'(末尾补零到 3 位有效数字)toDP 与 toFixed 的区别
toDP(2) | toFixed(2) | |
|---|---|---|
| 返回 | Decimal('1.24') | string('1.24') |
| 补零 | 不补(1.2 → '1.2') | 补零(1.2 → '1.20') |
| 用途 | 继续运算 | 展示、传输 |
js
new Decimal('1.2').toDP(2).toString() // '1.2'
new Decimal('1.2').toFixed(2) // '1.20'4. toNearest(n?, rounding?)
舍入到 n 的最近倍数(n 默认 1):
js
new Decimal('1.2').toNearest(0.5) // '1'(最近的 0.5 倍数)
new Decimal('-1.2').toNearest(0.5) // '-1'
new Decimal('2.5').toNearest(5) // '5'
new Decimal('7.5').toNearest(5) // '10'
new Decimal('2.5').toNearest(5, Decimal.ROUND_HALF_DOWN) // '0'
new Decimal('1.2').toNearest() // '1'(n 默认 1,即取整)
new Decimal(15).toNearest(10) // '20'
new Decimal('1.5').toNearest(1, Decimal.ROUND_HALF_EVEN) // '2'5. toFraction(maxDenominator?)
转为最简分数,返回 两个 Decimal 组成的数组 [分子, 分母]:
js
const pi = new Decimal(355).div(113); // '3.1415929204'
pi.toFraction()
// [ '31415929203539823009', '10000000000000000000' ](精确分数)
pi.toFraction(1000)
// [ '355', '113' ](限制最大分母 1000,得到近似分数)
pi.toFraction(5)
// [ '16', '5' ](限制最大分母 5)
// 数组元素是 Decimal 实例
pi.toFraction(1000)[0] instanceof Decimal // trueNOTE
maxDenominator 是「最大分母」:给一个上界,找到分母不超过它的最简分数。不给参数则返回精确分数(分子分母可能很大)。
6. 进制输出:toBinary / toOctal / toHex
js
const x = new Decimal('255.9375');
x.toBinary() // '0b11111111.1111'
x.toOctal() // '0o377.74'
x.toHex() // '0xff.f'(别名 toHexadecimal)
// 第二个参数:有效数字位数(二进制用 p 指数表示)
x.toBinary(13) // '0b1.11111111111p+7'
// 反过来,这些字符串可以直接再构造
new Decimal('0b11111111.1111') // '255.9375'NOTE
toBinary / toOctal / toHex 都接受 (significantDigits?, rounding?),输出为带前缀的字符串。
7. 指数显示规则速记
toString 使用科学计数法当且仅当 指数 ≥ toExpPos(默认 21)或 ≤ toExpNeg(默认 -7):
js
new Decimal('1e20').toString() // '100000000000000000000'
new Decimal('1e21').toString() // '1e+21'
new Decimal('1e-6').toString() // '0.000001'
new Decimal('1e-7').toString() // '1e-7'想始终显示普通形式 → toFixed();想始终显示科学计数法 → toExponential()。
8. 内部只读属性:dp() / sd() / e
| 方法/属性 | 返回 | 说明 |
|---|---|---|
decimalPlaces() / dp() | number | 小数位数(不计末尾零:'1.2300' → 2) |
precision() / sd() | number | 有效数字位数(不计末尾零:'1.2300' → 3) |
sd(true) | number | 有效数字位数(计末尾零:'100' → 3) |
e | number | 指数('1e21' → 21) |
js
new Decimal('1.2300').dp() // 2
new Decimal('1.2300').sd() // 3
new Decimal('100').sd() // 1
new Decimal('100').sd(true) // 3
new Decimal('0.00012345').sd() // 5
new Decimal('123.45').precision() // 5
new Decimal('0.0001').dp() // 4
new Decimal('1e-7').dp() // 7
new Decimal('1e21').e // 21