Skip to content

格式化与输出

格式化方法分两类:

  • 返回字符串toString / valueOf / toJSON / toFixed / toExponential / toPrecision / toBinary / toOctal / toHex
  • 返回 DecimaltoDP / toSD / toNearest / toFraction(返回 Decimal 数组)
  • 返回 numbertoNumber

1. 基础转换:toString / valueOf / toJSON / toNumber

方法返回类型说明
toString()string十进制字符串;按 toExpNeg/toExpPos 决定是否科学计数法;-0'0'
valueOf()stringtoString(),但 -0'-0'
toJSON()stringtoString(),供 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

toDPdecimalPlaces 不允许负数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  // true

NOTE

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)
enumber指数('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

相关章节