toDecimal
1. AutoDecimal:轻松解决 JavaScript 运算精度问题
2. AutoDecimal:轻松解决 JavaScript 运算精度问题之跳过转换
3. AutoDecimal:轻松解决 JavaScript 运算精度问题之显式转换
书接上篇。
限制
由于一些限制,导致在显式使用 toDecimal
时,如果想把某个计算做特殊处理,参数无法传递变量,只能使用基本类型字面量。如:
ts
const num = (0.1111 + 0.2222).toDecimal({
callMethod: 'toFixed', precision: 3, roundingModes: 'ROUND_UP'
})
// 结果为 0.334
// 上述表达式会被转换为
// const num = new Decimal(0.1111).plus(0.2222).toFixed(3, 0)
像上述使用方式是没有问题的。可以正常转换,但是如果想把属性提取出来或者通过参数或者变量传递进来的话
ts
const precision = 3
const num = (0.1111 + 0.2222).toDecimal({
callMethod: 'toFixed', precision, roundingModes: 'ROUND_UP'
})
// 结果为 0.3333
// 如果没有在 vite.config 中配置 toDecimal 参数,将使用默认参数进行转换
// 上述表达式会被转换为
// const num = new Decimal(0.1111).plus(0.2222).toNumber()
这样的使用方式就会无法解析,所以得到的结果是 0.3333
。因为传递的参数无法被解析,所以会使用默认的参数进行转换。
如果在 vite.config
中进行了相应的配置,如:
ts
defineConfig({
plugins: [
...
AutoDecimal({
toDecimal: {
callMethod: 'toFixed',
precision: 2,
roundingModes: 'ROUND_UP'
}
})
]
})
那么:
ts
const precision = 3
const num = (0.1111 + 0.2222).toDecimal({
callMethod: 'toFixed', precision, roundingModes: 'ROUND_UP'
})
// 结果为 0.34
// 上述表达式会被转换为
// const num = new Decimal(0.1111).plus(0.2222).toFixed(2, 0)
解决办法
为了解决无法传递变量的问题,现将 callMethod
添加了一个新值 decimal
。当 callMethod: 'decimal'
时,表达式将会返回一个 Decimal
实例。
ts
const precision = 3
const num = (0.1111 + 0.2222).toDecimal({ callMethod: 'decimal'})
// 此时,num 为 Decimal,所以可以直接使用 Decimal 的实例方法进行操作,也可是传递变量等任意操作
num.toFixed(precision)
num.abs()
num.comparedTo(precision)
num.div(10)
num.lessThan(precision)
num.isFinite()
...
Typescript
如果使用的是 typescript
的话,想要得到正确的返回类型,那么需要手动创建一个 d.ts 文件并添加 decimal
类型
ts
export {}
declare module 'unplugin-auto-decimal/types' {
interface AutoDecimal {
// 填写项目中对应的包类型即可
decimal: import('decimal.js-light').Decimal
}
}