react-util-tools 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +254 -0
- package/dist/index.cjs +943 -0
- package/dist/index.d.cts +154 -0
- package/dist/index.d.ts +154 -0
- package/dist/index.js +852 -0
- package/package.json +50 -0
- package/src/address/README.md +196 -0
- package/src/address/index.ts +41 -0
- package/src/date/README.md +539 -0
- package/src/date/index.ts +330 -0
- package/src/date/utc/README.md +779 -0
- package/src/date/utc/index.ts +374 -0
- package/src/decimal/README.md +425 -0
- package/src/decimal/index.ts +9 -0
- package/src/decimal/utils/README.md +474 -0
- package/src/decimal/utils/index.ts +244 -0
- package/src/device/README.md +441 -0
- package/src/device/index.ts +214 -0
- package/src/format/README.md +335 -0
- package/src/format/index.ts +189 -0
- package/src/index.ts +107 -0
- package/src/throttle/README.md +152 -0
- package/src/throttle/index.ts +83 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
# Decimal 工具
|
|
2
|
+
|
|
3
|
+
高精度十进制运算库,基于 [decimal.js](https://github.com/MikeMcl/decimal.js/)。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install your-package-name decimal.js
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 使用方法
|
|
12
|
+
|
|
13
|
+
### 导入
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { Decimal } from 'your-package-name'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 为什么需要 Decimal.js
|
|
20
|
+
|
|
21
|
+
JavaScript 的 Number 类型使用 IEEE 754 双精度浮点数,会导致精度问题:
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
0.1 + 0.2 // 0.30000000000000004
|
|
25
|
+
0.3 - 0.1 // 0.19999999999999998
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Decimal.js 提供任意精度的十进制运算,解决浮点数精度问题。
|
|
29
|
+
|
|
30
|
+
## 基础用法
|
|
31
|
+
|
|
32
|
+
### 创建 Decimal 实例
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { Decimal } from 'your-package-name'
|
|
36
|
+
|
|
37
|
+
// 从数字创建
|
|
38
|
+
const x = new Decimal(123.456)
|
|
39
|
+
|
|
40
|
+
// 从字符串创建(推荐)
|
|
41
|
+
const y = new Decimal('123.456')
|
|
42
|
+
|
|
43
|
+
// 从另一个 Decimal 创建
|
|
44
|
+
const z = new Decimal(x)
|
|
45
|
+
|
|
46
|
+
// 科学计数法
|
|
47
|
+
const a = new Decimal('1.23e+5') // 123000
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 基本运算
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { Decimal } from 'your-package-name'
|
|
54
|
+
|
|
55
|
+
const x = new Decimal('0.1')
|
|
56
|
+
const y = new Decimal('0.2')
|
|
57
|
+
|
|
58
|
+
// 加法
|
|
59
|
+
x.plus(y) // Decimal(0.3)
|
|
60
|
+
x.add(y) // 同 plus
|
|
61
|
+
|
|
62
|
+
// 减法
|
|
63
|
+
y.minus(x) // Decimal(0.1)
|
|
64
|
+
y.sub(x) // 同 minus
|
|
65
|
+
|
|
66
|
+
// 乘法
|
|
67
|
+
x.times(y) // Decimal(0.02)
|
|
68
|
+
x.mul(y) // 同 times
|
|
69
|
+
|
|
70
|
+
// 除法
|
|
71
|
+
y.dividedBy(x) // Decimal(2)
|
|
72
|
+
y.div(x) // 同 dividedBy
|
|
73
|
+
|
|
74
|
+
// 取模
|
|
75
|
+
new Decimal(10).modulo(3) // Decimal(1)
|
|
76
|
+
new Decimal(10).mod(3) // 同 modulo
|
|
77
|
+
|
|
78
|
+
// 幂运算
|
|
79
|
+
new Decimal(2).pow(3) // Decimal(8)
|
|
80
|
+
|
|
81
|
+
// 平方根
|
|
82
|
+
new Decimal(9).sqrt() // Decimal(3)
|
|
83
|
+
|
|
84
|
+
// 绝对值
|
|
85
|
+
new Decimal(-5).abs() // Decimal(5)
|
|
86
|
+
|
|
87
|
+
// 取反
|
|
88
|
+
new Decimal(5).negated() // Decimal(-5)
|
|
89
|
+
new Decimal(5).neg() // 同 negated
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 比较运算
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { Decimal } from 'your-package-name'
|
|
96
|
+
|
|
97
|
+
const x = new Decimal('0.1')
|
|
98
|
+
const y = new Decimal('0.2')
|
|
99
|
+
|
|
100
|
+
// 等于
|
|
101
|
+
x.equals(y) // false
|
|
102
|
+
x.eq(y) // 同 equals
|
|
103
|
+
|
|
104
|
+
// 大于
|
|
105
|
+
y.greaterThan(x) // true
|
|
106
|
+
y.gt(x) // 同 greaterThan
|
|
107
|
+
|
|
108
|
+
// 大于等于
|
|
109
|
+
y.greaterThanOrEqualTo(x) // true
|
|
110
|
+
y.gte(x) // 同 greaterThanOrEqualTo
|
|
111
|
+
|
|
112
|
+
// 小于
|
|
113
|
+
x.lessThan(y) // true
|
|
114
|
+
x.lt(y) // 同 lessThan
|
|
115
|
+
|
|
116
|
+
// 小于等于
|
|
117
|
+
x.lessThanOrEqualTo(y) // true
|
|
118
|
+
x.lte(y) // 同 lessThanOrEqualTo
|
|
119
|
+
|
|
120
|
+
// 比较(返回 -1, 0, 1)
|
|
121
|
+
x.comparedTo(y) // -1
|
|
122
|
+
x.cmp(y) // 同 comparedTo
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 格式化输出
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { Decimal } from 'your-package-name'
|
|
129
|
+
|
|
130
|
+
const x = new Decimal('1234.5678')
|
|
131
|
+
|
|
132
|
+
// 转为字符串
|
|
133
|
+
x.toString() // "1234.5678"
|
|
134
|
+
|
|
135
|
+
// 转为数字
|
|
136
|
+
x.toNumber() // 1234.5678
|
|
137
|
+
|
|
138
|
+
// 固定小数位数
|
|
139
|
+
x.toFixed(2) // "1234.57"
|
|
140
|
+
x.toFixed(0) // "1235"
|
|
141
|
+
|
|
142
|
+
// 指定有效数字
|
|
143
|
+
x.toPrecision(4) // "1235"
|
|
144
|
+
|
|
145
|
+
// 科学计数法
|
|
146
|
+
x.toExponential() // "1.2345678e+3"
|
|
147
|
+
x.toExponential(2) // "1.23e+3"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 舍入模式
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { Decimal } from 'your-package-name'
|
|
154
|
+
|
|
155
|
+
const x = new Decimal('1.5')
|
|
156
|
+
|
|
157
|
+
// 设置全局舍入模式
|
|
158
|
+
Decimal.set({ rounding: Decimal.ROUND_HALF_UP })
|
|
159
|
+
|
|
160
|
+
// 舍入模式常量
|
|
161
|
+
Decimal.ROUND_UP // 0 - 向上舍入(远离零)
|
|
162
|
+
Decimal.ROUND_DOWN // 1 - 向下舍入(趋向零)
|
|
163
|
+
Decimal.ROUND_CEIL // 2 - 向正无穷舍入
|
|
164
|
+
Decimal.ROUND_FLOOR // 3 - 向负无穷舍入
|
|
165
|
+
Decimal.ROUND_HALF_UP // 4 - 四舍五入(默认)
|
|
166
|
+
Decimal.ROUND_HALF_DOWN // 5 - 五舍六入
|
|
167
|
+
Decimal.ROUND_HALF_EVEN // 6 - 银行家舍入
|
|
168
|
+
Decimal.ROUND_HALF_CEIL // 7 - 向正无穷四舍五入
|
|
169
|
+
Decimal.ROUND_HALF_FLOOR // 8 - 向负无穷四舍五入
|
|
170
|
+
|
|
171
|
+
// 使用舍入
|
|
172
|
+
x.toDecimalPlaces(0) // Decimal(2) - 使用当前舍入模式
|
|
173
|
+
x.toDP(0) // 同 toDecimalPlaces
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 精度设置
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { Decimal } from 'your-package-name'
|
|
180
|
+
|
|
181
|
+
// 设置全局精度(有效数字位数)
|
|
182
|
+
Decimal.set({ precision: 20 })
|
|
183
|
+
|
|
184
|
+
// 设置全局配置
|
|
185
|
+
Decimal.set({
|
|
186
|
+
precision: 20,
|
|
187
|
+
rounding: Decimal.ROUND_HALF_UP,
|
|
188
|
+
toExpNeg: -7,
|
|
189
|
+
toExpPos: 21
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
// 获取当前配置
|
|
193
|
+
const config = Decimal.config()
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## 实际应用场景
|
|
197
|
+
|
|
198
|
+
### 金额计算
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { Decimal } from 'your-package-name'
|
|
202
|
+
|
|
203
|
+
// 商品价格计算
|
|
204
|
+
const price = new Decimal('19.99')
|
|
205
|
+
const quantity = new Decimal('3')
|
|
206
|
+
const total = price.times(quantity)
|
|
207
|
+
|
|
208
|
+
console.log(total.toFixed(2)) // "59.97"
|
|
209
|
+
|
|
210
|
+
// 折扣计算
|
|
211
|
+
const discount = new Decimal('0.15') // 15% 折扣
|
|
212
|
+
const discountAmount = total.times(discount)
|
|
213
|
+
const finalPrice = total.minus(discountAmount)
|
|
214
|
+
|
|
215
|
+
console.log(finalPrice.toFixed(2)) // "50.97"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 税费计算
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import { Decimal } from 'your-package-name'
|
|
222
|
+
|
|
223
|
+
const amount = new Decimal('100')
|
|
224
|
+
const taxRate = new Decimal('0.13') // 13% 税率
|
|
225
|
+
|
|
226
|
+
// 计算税额
|
|
227
|
+
const tax = amount.times(taxRate)
|
|
228
|
+
console.log(tax.toFixed(2)) // "13.00"
|
|
229
|
+
|
|
230
|
+
// 含税总额
|
|
231
|
+
const totalWithTax = amount.plus(tax)
|
|
232
|
+
console.log(totalWithTax.toFixed(2)) // "113.00"
|
|
233
|
+
|
|
234
|
+
// 从含税价反推原价
|
|
235
|
+
const priceWithTax = new Decimal('113')
|
|
236
|
+
const originalPrice = priceWithTax.dividedBy(new Decimal('1').plus(taxRate))
|
|
237
|
+
console.log(originalPrice.toFixed(2)) // "100.00"
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### 利息计算
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { Decimal } from 'your-package-name'
|
|
244
|
+
|
|
245
|
+
// 本金
|
|
246
|
+
const principal = new Decimal('10000')
|
|
247
|
+
// 年利率 3.5%
|
|
248
|
+
const annualRate = new Decimal('0.035')
|
|
249
|
+
// 期数(月)
|
|
250
|
+
const months = 12
|
|
251
|
+
|
|
252
|
+
// 月利率
|
|
253
|
+
const monthlyRate = annualRate.dividedBy(12)
|
|
254
|
+
|
|
255
|
+
// 简单利息
|
|
256
|
+
const simpleInterest = principal.times(annualRate)
|
|
257
|
+
console.log(`年利息: ${simpleInterest.toFixed(2)}`) // "350.00"
|
|
258
|
+
|
|
259
|
+
// 复利计算
|
|
260
|
+
const compoundInterest = principal.times(
|
|
261
|
+
new Decimal(1).plus(monthlyRate).pow(months)
|
|
262
|
+
).minus(principal)
|
|
263
|
+
console.log(`复利: ${compoundInterest.toFixed(2)}`) // "355.82"
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 汇率转换
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import { Decimal } from 'your-package-name'
|
|
270
|
+
|
|
271
|
+
const cnyAmount = new Decimal('1000') // 人民币
|
|
272
|
+
const exchangeRate = new Decimal('7.2345') // 汇率
|
|
273
|
+
|
|
274
|
+
// 人民币转美元
|
|
275
|
+
const usdAmount = cnyAmount.dividedBy(exchangeRate)
|
|
276
|
+
console.log(`$${usdAmount.toFixed(2)}`) // "$138.23"
|
|
277
|
+
|
|
278
|
+
// 美元转人民币
|
|
279
|
+
const cnyBack = usdAmount.times(exchangeRate)
|
|
280
|
+
console.log(`¥${cnyBack.toFixed(2)}`) // "¥1000.00"
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### 百分比计算
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
import { Decimal } from 'your-package-name'
|
|
287
|
+
|
|
288
|
+
const total = new Decimal('500')
|
|
289
|
+
const part = new Decimal('125')
|
|
290
|
+
|
|
291
|
+
// 计算百分比
|
|
292
|
+
const percentage = part.dividedBy(total).times(100)
|
|
293
|
+
console.log(`${percentage.toFixed(2)}%`) // "25.00%"
|
|
294
|
+
|
|
295
|
+
// 从百分比计算数值
|
|
296
|
+
const percent = new Decimal('25')
|
|
297
|
+
const value = total.times(percent.dividedBy(100))
|
|
298
|
+
console.log(value.toFixed(2)) // "125.00"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### 分账计算
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import { Decimal } from 'your-package-name'
|
|
305
|
+
|
|
306
|
+
const totalAmount = new Decimal('100')
|
|
307
|
+
const people = 3
|
|
308
|
+
|
|
309
|
+
// 平均分配
|
|
310
|
+
const perPerson = totalAmount.dividedBy(people)
|
|
311
|
+
console.log(perPerson.toFixed(2)) // "33.33"
|
|
312
|
+
|
|
313
|
+
// 处理余数
|
|
314
|
+
const allocated = perPerson.times(people)
|
|
315
|
+
const remainder = totalAmount.minus(allocated)
|
|
316
|
+
console.log(`余额: ${remainder.toFixed(2)}`) // "0.01"
|
|
317
|
+
|
|
318
|
+
// 按比例分配
|
|
319
|
+
const ratios = [
|
|
320
|
+
new Decimal('0.5'), // 50%
|
|
321
|
+
new Decimal('0.3'), // 30%
|
|
322
|
+
new Decimal('0.2') // 20%
|
|
323
|
+
]
|
|
324
|
+
|
|
325
|
+
ratios.forEach((ratio, index) => {
|
|
326
|
+
const share = totalAmount.times(ratio)
|
|
327
|
+
console.log(`第${index + 1}人: ${share.toFixed(2)}`)
|
|
328
|
+
})
|
|
329
|
+
// 第1人: 50.00
|
|
330
|
+
// 第2人: 30.00
|
|
331
|
+
// 第3人: 20.00
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### 统计计算
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
import { Decimal } from 'your-package-name'
|
|
338
|
+
|
|
339
|
+
const values = [
|
|
340
|
+
new Decimal('10.5'),
|
|
341
|
+
new Decimal('20.3'),
|
|
342
|
+
new Decimal('15.7'),
|
|
343
|
+
new Decimal('30.2')
|
|
344
|
+
]
|
|
345
|
+
|
|
346
|
+
// 求和
|
|
347
|
+
const sum = values.reduce((acc, val) => acc.plus(val), new Decimal(0))
|
|
348
|
+
console.log(`总和: ${sum.toFixed(2)}`) // "76.70"
|
|
349
|
+
|
|
350
|
+
// 平均值
|
|
351
|
+
const average = sum.dividedBy(values.length)
|
|
352
|
+
console.log(`平均值: ${average.toFixed(2)}`) // "19.18"
|
|
353
|
+
|
|
354
|
+
// 最大值
|
|
355
|
+
const max = values.reduce((max, val) => val.greaterThan(max) ? val : max)
|
|
356
|
+
console.log(`最大值: ${max.toFixed(2)}`) // "30.20"
|
|
357
|
+
|
|
358
|
+
// 最小值
|
|
359
|
+
const min = values.reduce((min, val) => val.lessThan(min) ? val : min)
|
|
360
|
+
console.log(`最小值: ${min.toFixed(2)}`) // "10.50"
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## 常用方法速查
|
|
364
|
+
|
|
365
|
+
### 运算方法
|
|
366
|
+
- `plus(n)` / `add(n)` - 加法
|
|
367
|
+
- `minus(n)` / `sub(n)` - 减法
|
|
368
|
+
- `times(n)` / `mul(n)` - 乘法
|
|
369
|
+
- `dividedBy(n)` / `div(n)` - 除法
|
|
370
|
+
- `modulo(n)` / `mod(n)` - 取模
|
|
371
|
+
- `pow(n)` - 幂运算
|
|
372
|
+
- `sqrt()` - 平方根
|
|
373
|
+
- `abs()` - 绝对值
|
|
374
|
+
- `negated()` / `neg()` - 取反
|
|
375
|
+
|
|
376
|
+
### 比较方法
|
|
377
|
+
- `equals(n)` / `eq(n)` - 等于
|
|
378
|
+
- `greaterThan(n)` / `gt(n)` - 大于
|
|
379
|
+
- `greaterThanOrEqualTo(n)` / `gte(n)` - 大于等于
|
|
380
|
+
- `lessThan(n)` / `lt(n)` - 小于
|
|
381
|
+
- `lessThanOrEqualTo(n)` / `lte(n)` - 小于等于
|
|
382
|
+
- `comparedTo(n)` / `cmp(n)` - 比较
|
|
383
|
+
|
|
384
|
+
### 格式化方法
|
|
385
|
+
- `toString()` - 转字符串
|
|
386
|
+
- `toNumber()` - 转数字
|
|
387
|
+
- `toFixed(dp)` - 固定小数位
|
|
388
|
+
- `toPrecision(sd)` - 指定有效数字
|
|
389
|
+
- `toExponential(dp)` - 科学计数法
|
|
390
|
+
- `toDecimalPlaces(dp)` / `toDP(dp)` - 舍入到指定小数位
|
|
391
|
+
|
|
392
|
+
### 判断方法
|
|
393
|
+
- `isZero()` - 是否为 0
|
|
394
|
+
- `isNaN()` - 是否为 NaN
|
|
395
|
+
- `isFinite()` - 是否有限
|
|
396
|
+
- `isInteger()` - 是否为整数
|
|
397
|
+
- `isNegative()` - 是否为负数
|
|
398
|
+
- `isPositive()` - 是否为正数
|
|
399
|
+
|
|
400
|
+
## TypeScript 支持
|
|
401
|
+
|
|
402
|
+
完整的 TypeScript 类型支持。
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
import { Decimal } from 'your-package-name'
|
|
406
|
+
|
|
407
|
+
const x: Decimal = new Decimal('123.456')
|
|
408
|
+
const result: Decimal = x.plus('10')
|
|
409
|
+
const str: string = result.toString()
|
|
410
|
+
const num: number = result.toNumber()
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## 注意事项
|
|
414
|
+
|
|
415
|
+
- 推荐使用字符串创建 Decimal 实例,避免浮点数精度问题
|
|
416
|
+
- 所有运算方法返回新的 Decimal 实例,不会修改原实例
|
|
417
|
+
- 大数运算会消耗更多内存和计算时间
|
|
418
|
+
- 金融计算建议设置合适的精度和舍入模式
|
|
419
|
+
- 详细文档请参考:https://mikemcl.github.io/decimal.js/
|
|
420
|
+
|
|
421
|
+
## 相关链接
|
|
422
|
+
|
|
423
|
+
- [Decimal.js 官方文档](https://mikemcl.github.io/decimal.js/)
|
|
424
|
+
- [Decimal.js GitHub](https://github.com/MikeMcl/decimal.js/)
|
|
425
|
+
- [API 参考](https://mikemcl.github.io/decimal.js/#methods)
|