@digitalwalletcorp/utils 0.2.0 → 0.4.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.
Files changed (112) hide show
  1. package/README.md +13 -13
  2. package/lib/crypto-util-DFJqfmuw.js +46 -0
  3. package/lib/crypto-util-DFJqfmuw.js.map +1 -0
  4. package/lib/crypto-util-DeZSGetI.cjs +2 -0
  5. package/lib/crypto-util-DeZSGetI.cjs.map +1 -0
  6. package/lib/crypto-util.cjs +2 -0
  7. package/lib/crypto-util.cjs.map +1 -0
  8. package/lib/crypto-util.d.cts +28 -0
  9. package/lib/crypto-util.d.ts +28 -0
  10. package/lib/crypto-util.js +7 -0
  11. package/lib/crypto-util.js.map +1 -0
  12. package/lib/date-util-CG7L8nSP.js +184 -0
  13. package/lib/date-util-CG7L8nSP.js.map +1 -0
  14. package/lib/date-util-DopNKy3u.cjs +2 -0
  15. package/lib/date-util-DopNKy3u.cjs.map +1 -0
  16. package/lib/date-util.cjs +2 -0
  17. package/lib/date-util.cjs.map +1 -0
  18. package/lib/date-util.d.cts +231 -0
  19. package/lib/date-util.d.ts +231 -0
  20. package/lib/date-util.js +23 -0
  21. package/lib/date-util.js.map +1 -0
  22. package/lib/decimal.cjs +2 -0
  23. package/lib/decimal.cjs.map +1 -0
  24. package/lib/decimal.d.cts +197 -0
  25. package/lib/decimal.d.ts +197 -0
  26. package/lib/decimal.js +227 -0
  27. package/lib/decimal.js.map +1 -0
  28. package/lib/file-util-D09BvDYY.cjs +2 -0
  29. package/lib/file-util-D09BvDYY.cjs.map +1 -0
  30. package/lib/file-util-H-c_eQcd.js +140 -0
  31. package/lib/file-util-H-c_eQcd.js.map +1 -0
  32. package/lib/file-util.cjs +2 -0
  33. package/lib/file-util.cjs.map +1 -0
  34. package/lib/file-util.d.cts +119 -0
  35. package/lib/file-util.d.ts +119 -0
  36. package/lib/file-util.js +18 -0
  37. package/lib/file-util.js.map +1 -0
  38. package/lib/html-util-Bxn5YDSK.cjs +2 -0
  39. package/lib/html-util-Bxn5YDSK.cjs.map +1 -0
  40. package/lib/html-util-CgMIuOsf.js +49 -0
  41. package/lib/html-util-CgMIuOsf.js.map +1 -0
  42. package/lib/html-util.cjs +2 -0
  43. package/lib/html-util.cjs.map +1 -0
  44. package/lib/html-util.d.cts +71 -0
  45. package/lib/html-util.d.ts +71 -0
  46. package/lib/html-util.js +8 -0
  47. package/lib/html-util.js.map +1 -0
  48. package/lib/index.cjs +1 -1
  49. package/lib/index.d.cts +8 -0
  50. package/lib/index.d.ts +8 -0
  51. package/lib/index.js +18 -2
  52. package/lib/index.js.map +1 -1
  53. package/lib/json-util-BvrFYh5E.cjs +3 -0
  54. package/lib/json-util-BvrFYh5E.cjs.map +1 -0
  55. package/lib/json-util-YX7xSF6R.js +136 -0
  56. package/lib/json-util-YX7xSF6R.js.map +1 -0
  57. package/lib/json-util.cjs +2 -0
  58. package/lib/json-util.cjs.map +1 -0
  59. package/lib/json-util.d.cts +58 -0
  60. package/lib/json-util.d.ts +58 -0
  61. package/lib/json-util.js +8 -0
  62. package/lib/json-util.js.map +1 -0
  63. package/lib/number-util-BA4KVFyF.js +198 -0
  64. package/lib/number-util-BA4KVFyF.js.map +1 -0
  65. package/lib/number-util-BaSf1wWH.cjs +2 -0
  66. package/lib/number-util-BaSf1wWH.cjs.map +1 -0
  67. package/lib/number-util.cjs +1 -1
  68. package/lib/number-util.d.cts +65 -51
  69. package/lib/number-util.d.ts +65 -51
  70. package/lib/number-util.js +19 -14
  71. package/lib/object-util-DhGi-PmA.js +204 -0
  72. package/lib/object-util-DhGi-PmA.js.map +1 -0
  73. package/lib/object-util-Z0Ah5J8A.cjs +2 -0
  74. package/lib/object-util-Z0Ah5J8A.cjs.map +1 -0
  75. package/lib/object-util.cjs +2 -0
  76. package/lib/object-util.cjs.map +1 -0
  77. package/lib/object-util.d.cts +157 -0
  78. package/lib/object-util.d.ts +157 -0
  79. package/lib/object-util.js +16 -0
  80. package/lib/object-util.js.map +1 -0
  81. package/lib/string-util-Cw0VgbIH.js +52 -0
  82. package/lib/string-util-Cw0VgbIH.js.map +1 -0
  83. package/lib/string-util-w2I5EYuY.cjs +2 -0
  84. package/lib/string-util-w2I5EYuY.cjs.map +1 -0
  85. package/lib/string-util.cjs +2 -0
  86. package/lib/string-util.cjs.map +1 -0
  87. package/lib/string-util.d.cts +51 -0
  88. package/lib/string-util.d.ts +51 -0
  89. package/lib/string-util.js +8 -0
  90. package/lib/string-util.js.map +1 -0
  91. package/package.json +26 -8
  92. package/src/crypto-util.ts +84 -0
  93. package/src/date-util.ts +448 -0
  94. package/src/decimal.ts +294 -0
  95. package/src/file-util.ts +281 -0
  96. package/src/html-util.ts +196 -0
  97. package/src/index.ts +8 -0
  98. package/src/json-util.ts +271 -0
  99. package/src/number-util.ts +141 -194
  100. package/src/object-util.ts +482 -0
  101. package/src/string-util.ts +115 -0
  102. package/lib/number-util-DHq-ux31.js +0 -253
  103. package/lib/number-util-DHq-ux31.js.map +0 -1
  104. package/lib/number-util-DiMi-j7B.cjs +0 -2
  105. package/lib/number-util-DiMi-j7B.cjs.map +0 -1
  106. package/lib/reg-exp-matcher.cjs +0 -2
  107. package/lib/reg-exp-matcher.cjs.map +0 -1
  108. package/lib/reg-exp-matcher.d.cts +0 -85
  109. package/lib/reg-exp-matcher.d.ts +0 -85
  110. package/lib/reg-exp-matcher.js +0 -94
  111. package/lib/reg-exp-matcher.js.map +0 -1
  112. package/src/reg-exp-matcher.ts +0 -154
@@ -1,41 +1,12 @@
1
- import { Big } from 'big.js';
1
+ import { Decimal, ROUNDING_MODE } from './decimal';
2
+ import type { NumberSource, RoundingMode } from './decimal';
2
3
 
3
- /**
4
- * 数値として扱える値の型
5
- */
6
- export type NumberSource = number | string | bigint;
4
+ export { ROUNDING_MODE };
5
+ export type { NumberSource, RoundingMode };
7
6
 
8
7
  // 64bit整数の範囲
9
- const MIN_LONG = Big('-9223372036854775808');
10
- const MAX_LONG = Big('9223372036854775807');
11
-
12
- /**
13
- * 丸めモード
14
- * 公開APIに内部の算術ライブラリ(big.js)の型を出さないよう、値を直接定義する(big.jsの丸めモードと同じ値)
15
- */
16
- export const ROUNDING_MODE = {
17
- /**
18
- * Rounds towards zero.
19
- * I.e. truncate, no rounding.
20
- */
21
- roundDown: 0,
22
- /**
23
- * Rounds towards nearest neighbour.
24
- * If equidistant, rounds away from zero.
25
- */
26
- roundHalfUp: 1,
27
- /**
28
- * Rounds towards nearest neighbour.
29
- * If equidistant, rounds towards even neighbour.
30
- */
31
- roundHalfEven: 2,
32
- /**
33
- * Rounds away from zero.
34
- */
35
- roundUp: 3
36
- } as const;
37
-
38
- export type RoundingMode = typeof ROUNDING_MODE[keyof typeof ROUNDING_MODE];
8
+ const MIN_LONG = new Decimal('-9223372036854775808');
9
+ const MAX_LONG = new Decimal('9223372036854775807');
39
10
 
40
11
  /** 数値パターン */
41
12
  const NUMBER_PATTERN = new RegExp('([\+\-]?)([0-9]*)[\.]?([0-9]*)');
@@ -43,10 +14,8 @@ const NUMBER_PATTERN = new RegExp('([\+\-]?)([0-9]*)[\.]?([0-9]*)');
43
14
  /** 数値として解釈できる文字列のパターン(符号・小数点・指数表記) */
44
15
  const NUMERIC_STRING_PATTERN = /^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i;
45
16
 
46
- function toBig(value: NumberSource): Big {
47
- // @types/big.js の型定義が bigint を含まないため、文字列にして渡す
48
- return Big(typeof value === 'bigint' ? value.toString() : value);
49
- }
17
+ // 空文字・空白のみの文字列はtrueを返す
18
+ const isBlank = (value: unknown): value is string => typeof value === 'string' && value.trim() === '';
50
19
 
51
20
  /**
52
21
  * long(64bit)の範囲(-9223372036854775808〜9223372036854775807)の値か判定する
@@ -63,21 +32,15 @@ function toBig(value: NumberSource): Big {
63
32
  export function isLongValue(value: string | bigint, options?: {
64
33
  minValue?: number;
65
34
  }): boolean {
66
- let min;
67
- if (options?.minValue != null) {
68
- try {
69
- min = Big(options.minValue);
70
- } catch (error) {
71
- min = MIN_LONG;
72
- }
73
- } else {
74
- min = MIN_LONG;
35
+ if (value == null || isBlank(value)) {
36
+ return false;
75
37
  }
38
+ const min = Number.isFinite(options?.minValue) ? new Decimal(options!.minValue) : MIN_LONG;
76
39
  try {
77
40
  // -9223372036854775808 <= value <= 9223372036854775807
78
- return min.lte(value.toString()) && MAX_LONG.gte(value.toString());
41
+ return min.lte(value) && MAX_LONG.gte(value);
79
42
  } catch (error) {
80
- // 数値以外やnullが渡された場合エラーになるためfalseを返却([big.js] Invalid number)
43
+ // 数値として解釈できない値
81
44
  return false;
82
45
  }
83
46
  }
@@ -104,8 +67,8 @@ export function formatComma(value: NumberSource | null | undefined, scale?: numb
104
67
  // "NaN" / "Infinity" / "-Infinity" を返却
105
68
  return String(value);
106
69
  }
107
- // toString()は1e21以上や1e-7以下を指数表記にするため、Bigで通常の表記に展開する
108
- strValue = Big(value).toFixed();
70
+ // toString()は1e21以上や1e-7以下を指数表記にするため、Decimalで通常の表記に展開する
71
+ strValue = new Decimal(value).toString();
109
72
  break;
110
73
  case 'string':
111
74
  strValue = removeComma(value).trim();
@@ -114,9 +77,9 @@ export function formatComma(value: NumberSource | null | undefined, scale?: numb
114
77
  return value;
115
78
  }
116
79
  if (/e/i.test(strValue)) {
117
- // 指数表記を通常の表記に展開する。Big.jsは '+' を受け付けないため外して渡し、表示用に付け直す
80
+ // 指数表記を通常の表記に展開する。表示用に '+' を付け直す
118
81
  const plusSign = strValue.startsWith('+') ? '+' : '';
119
- strValue = `${plusSign}${Big(strValue.replace(/^\+/, '')).toFixed()}`;
82
+ strValue = `${plusSign}${new Decimal(strValue).toString()}`;
120
83
  }
121
84
  break;
122
85
  default:
@@ -128,11 +91,10 @@ export function formatComma(value: NumberSource | null | undefined, scale?: numb
128
91
  let natural = matches[2] || '0';
129
92
  let decimal = matches[3];
130
93
  let dp: number;
131
- // Big.jsに渡すとき '+' が付いているとエラーになる
132
- let big = new Big(`${sign === '-' ? '-' : ''}${natural}.${decimal}`);
94
+ let decimalValue = new Decimal(`${sign === '-' ? '-' : ''}${natural}.${decimal}`);
133
95
  if (scale != null) {
134
- big = big.round(scale, roundingMode ?? ROUNDING_MODE.roundHalfUp);
135
- const roundedMatches = NUMBER_PATTERN.exec(big.toFixed()) as RegExpExecArray;
96
+ decimalValue = decimalValue.round(scale, roundingMode ?? ROUNDING_MODE.roundHalfUp);
97
+ const roundedMatches = NUMBER_PATTERN.exec(decimalValue.toString()) as RegExpExecArray;
136
98
  natural = roundedMatches[2];
137
99
  decimal = roundedMatches[3];
138
100
  dp = scale;
@@ -140,7 +102,7 @@ export function formatComma(value: NumberSource | null | undefined, scale?: numb
140
102
  dp = decimal.length;
141
103
  }
142
104
  // 丸めた結果がゼロになる場合('-0.001' を小数2桁にするなど)に "-0.00" とならないよう、丸めた後の値で判定する
143
- const displaySign = big.eq(0) ? '' : sign;
105
+ const displaySign = decimalValue.eq(0) ? '' : sign;
144
106
  natural = natural.replace(/(\d)(?=(\d{3})+$)/g, '$1,');
145
107
  decimal = `${decimal}${'0'.repeat(dp)}`.substring(0, dp);
146
108
  return decimal === ''
@@ -177,51 +139,6 @@ export interface OperationItem {
177
139
  value: NumberSource | null | undefined;
178
140
  }
179
141
 
180
- // null/undefined/空文字/NaNはtrueを返す
181
- const isLikelyUndefined = (b: NumberSource | null | undefined): b is null | undefined | '' => b == null || b === '' || (typeof b === 'number' && Number.isNaN(b));
182
-
183
- // 演算の初期値。null/undefined/空文字/NaNはゼロとみなす
184
- const toInitialBig = (value: NumberSource | null | undefined): Big => isLikelyUndefined(value) ? Big(0) : toBig(value);
185
-
186
- const operators: Record<Operator, (a: Big, b: NumberSource | null | undefined) => Big> = {
187
- // null/undefined/空文字/NaNはゼロとみなす
188
- add: (a, b) => a.add(isLikelyUndefined(b) ? 0 : toBig(b)),
189
- // null/undefined/空文字/NaNはゼロとみなす
190
- sub: (a, b) => a.sub(isLikelyUndefined(b) ? 0 : toBig(b)),
191
- /**
192
- * 乗算の場合の'b'の値は、計算したい対象によってゼロとみなすのか無視して元の値を保持したいのかの概念が異なる
193
- * ゼロとみなしたい場合の例:
194
- * 手数料 x 件数
195
- * → このとき件数が未定義(≒ 0)だったら手数料総計は0が適切
196
- * 無視して元の値を保持したい場合の例:
197
- * 商品価格 x 割引率
198
- * → このとき割引率が未定義(≒ 1)だったら販売価格は元の値(商品価格)が適切
199
- *
200
- * この関数のデフォルトの挙動は「ゼロとみなす」とする
201
- * 1とみなすと、第1引数のnullはゼロとみなすため times(3, null) = 3、times(null, 3) = 0 のように引数の順序で結果が変わってしまう
202
- * 元の値を保持したいケースでは
203
- * NumberUtil.times(price, discount ?? 1)
204
- * のように、discountが未定義だった場合のフォールバック値を指定する
205
- */
206
- // null/undefined/空文字/NaNはゼロとみなす
207
- times: (a, b) => a.times(isLikelyUndefined(b) ? 0 : toBig(b)),
208
- /**
209
- * 除算の場合`isLikelyUndefined(b) = true`をゼロとみなす挙動にすると、0, null, undefined, 空文字などすべてゼロ除算エラーになってしまうため
210
- * 割る値に限り1とみなし、元の値を保持する挙動とする(明示的に0を指定した場合はゼロ除算エラー)
211
- * 例) 割引率で割る計算で、割引率が未定義なら元の値が適切
212
- */
213
- // null/undefined/空文字/NaNは1とみなす(a / 1 = a)。0を演算対象にするとゼロ除算エラーが発生する
214
- div: (a, b) => isLikelyUndefined(b) ? a : a.div(toBig(b))
215
- };
216
-
217
- function calcAsBig(initialValue: NumberSource | null | undefined, operationItems: OperationItem[]): Big {
218
- let bigvalue = toInitialBig(initialValue);
219
- for (const item of operationItems) {
220
- bigvalue = operators[item.operator](bigvalue, item.value);
221
- }
222
- return bigvalue;
223
- }
224
-
225
142
  /**
226
143
  * 複数の演算をまとめて計算する
227
144
  * 計算途中は精度を保持し、最後にnumberへ変換する
@@ -243,7 +160,6 @@ function calcAsBig(initialValue: NumberSource | null | undefined, operationItems
243
160
  * 146 * 2 = 292
244
161
  * 292 / 3 = 97.33333333
245
162
  *
246
- * 数学的な感覚だと 123 + 123 - ((100 * 2) / 3) = 229.33333333 となるが、この関数はそのような計算を行わない
247
163
  * null等の扱いは add / sub / times / div と同じ
248
164
  * 戻り値はnumberのため、Number.MAX_SAFE_INTEGERを超える結果は精度が落ちる
249
165
  *
@@ -260,11 +176,14 @@ export function calc(initialValue: NumberSource | null | undefined, operationIte
260
176
  scale?: number;
261
177
  roundingMode?: RoundingMode;
262
178
  }): number {
263
- let bigvalue = calcAsBig(initialValue, operationItems);
179
+ let decimal = new Decimal(initialValue);
180
+ for (const item of operationItems) {
181
+ decimal = decimal[item.operator](item.value);
182
+ }
264
183
  if (options?.scale != null) {
265
- bigvalue = bigvalue.round(options.scale, options.roundingMode ?? ROUNDING_MODE.roundHalfUp);
184
+ decimal = decimal.round(options.scale, options.roundingMode ?? ROUNDING_MODE.roundHalfUp);
266
185
  }
267
- return bigvalue.toNumber();
186
+ return decimal.toNumber();
268
187
  }
269
188
 
270
189
  /**
@@ -277,11 +196,11 @@ export function calc(initialValue: NumberSource | null | undefined, operationIte
277
196
  * @returns {number}
278
197
  */
279
198
  export function add(value1: NumberSource | null | undefined, ...value2: (NumberSource | null | undefined)[]): number {
280
- let bigvalue = toInitialBig(value1);
199
+ let decimal = new Decimal(value1);
281
200
  for (const value of value2) {
282
- bigvalue = operators.add(bigvalue, value);
201
+ decimal = decimal.add(value);
283
202
  }
284
- return bigvalue.toNumber();
203
+ return decimal.toNumber();
285
204
  }
286
205
 
287
206
  /**
@@ -294,11 +213,11 @@ export function add(value1: NumberSource | null | undefined, ...value2: (NumberS
294
213
  * @returns {number}
295
214
  */
296
215
  export function sub(value1: NumberSource | null | undefined, ...value2: (NumberSource | null | undefined)[]): number {
297
- let bigvalue = toInitialBig(value1);
216
+ let decimal = new Decimal(value1);
298
217
  for (const value of value2) {
299
- bigvalue = operators.sub(bigvalue, value);
218
+ decimal = decimal.sub(value);
300
219
  }
301
- return bigvalue.toNumber();
220
+ return decimal.toNumber();
302
221
  }
303
222
 
304
223
  /**
@@ -312,11 +231,11 @@ export function sub(value1: NumberSource | null | undefined, ...value2: (NumberS
312
231
  * @returns {number}
313
232
  */
314
233
  export function times(value1: NumberSource | null | undefined, ...value2: (NumberSource | null | undefined)[]): number {
315
- let bigvalue = toInitialBig(value1);
234
+ let decimal = new Decimal(value1);
316
235
  for (const value of value2) {
317
- bigvalue = operators.times(bigvalue, value);
236
+ decimal = decimal.times(value);
318
237
  }
319
- return bigvalue.toNumber();
238
+ return decimal.toNumber();
320
239
  }
321
240
 
322
241
  /**
@@ -330,11 +249,89 @@ export function times(value1: NumberSource | null | undefined, ...value2: (Numbe
330
249
  * @returns {number}
331
250
  */
332
251
  export function div(value1: NumberSource | null | undefined, ...value2: (NumberSource | null | undefined)[]): number {
333
- let bigvalue = toInitialBig(value1);
252
+ let decimal = new Decimal(value1);
334
253
  for (const value of value2) {
335
- bigvalue = operators.div(bigvalue, value);
254
+ decimal = decimal.div(value);
336
255
  }
337
- return bigvalue.toNumber();
256
+ return decimal.toNumber();
257
+ }
258
+
259
+ /**
260
+ * 2つの値を数値として比較する
261
+ * null/undefined/空文字/NaNは0と見做す
262
+ * 数値として解釈できない文字列やInfinityを指定した場合はTypeErrorになる
263
+ *
264
+ * @param {NumberSource | null | undefined} value1
265
+ * @param {NumberSource | null | undefined} value2
266
+ * @returns {-1 | 0 | 1} value1がvalue2より小さい場合は-1、等しい場合は0、大きい場合は1
267
+ */
268
+ export function compareTo(value1: NumberSource | null | undefined, value2: NumberSource | null | undefined): -1 | 0 | 1 {
269
+ return new Decimal(value1).compareTo(value2);
270
+ }
271
+
272
+ /**
273
+ * 2つの値が数値として等しいかを返す
274
+ * null/undefined/空文字/NaNは0と見做す
275
+ * 数値として解釈できない文字列やInfinityを指定した場合はTypeErrorになる
276
+ *
277
+ * @param {NumberSource | null | undefined} value1
278
+ * @param {NumberSource | null | undefined} value2
279
+ * @returns {boolean}
280
+ */
281
+ export function eq(value1: NumberSource | null | undefined, value2: NumberSource | null | undefined): boolean {
282
+ return compareTo(value1, value2) === 0;
283
+ }
284
+
285
+ /**
286
+ * value1がvalue2より小さいかを返す
287
+ * null/undefined/空文字/NaNは0と見做す
288
+ * 数値として解釈できない文字列やInfinityを指定した場合はTypeErrorになる
289
+ *
290
+ * @param {NumberSource | null | undefined} value1
291
+ * @param {NumberSource | null | undefined} value2
292
+ * @returns {boolean}
293
+ */
294
+ export function lt(value1: NumberSource | null | undefined, value2: NumberSource | null | undefined): boolean {
295
+ return compareTo(value1, value2) < 0;
296
+ }
297
+
298
+ /**
299
+ * value1がvalue2以下かを返す
300
+ * null/undefined/空文字/NaNは0と見做す
301
+ * 数値として解釈できない文字列やInfinityを指定した場合はTypeErrorになる
302
+ *
303
+ * @param {NumberSource | null | undefined} value1
304
+ * @param {NumberSource | null | undefined} value2
305
+ * @returns {boolean}
306
+ */
307
+ export function lte(value1: NumberSource | null | undefined, value2: NumberSource | null | undefined): boolean {
308
+ return compareTo(value1, value2) <= 0;
309
+ }
310
+
311
+ /**
312
+ * value1がvalue2より大きいかを返す
313
+ * null/undefined/空文字/NaNは0と見做す
314
+ * 数値として解釈できない文字列やInfinityを指定した場合はTypeErrorになる
315
+ *
316
+ * @param {NumberSource | null | undefined} value1
317
+ * @param {NumberSource | null | undefined} value2
318
+ * @returns {boolean}
319
+ */
320
+ export function gt(value1: NumberSource | null | undefined, value2: NumberSource | null | undefined): boolean {
321
+ return 0 < compareTo(value1, value2);
322
+ }
323
+
324
+ /**
325
+ * value1がvalue2以上かを返す
326
+ * null/undefined/空文字/NaNは0と見做す
327
+ * 数値として解釈できない文字列やInfinityを指定した場合はTypeErrorになる
328
+ *
329
+ * @param {NumberSource | null | undefined} value1
330
+ * @param {NumberSource | null | undefined} value2
331
+ * @returns {boolean}
332
+ */
333
+ export function gte(value1: NumberSource | null | undefined, value2: NumberSource | null | undefined): boolean {
334
+ return 0 <= compareTo(value1, value2);
338
335
  }
339
336
 
340
337
  /**
@@ -345,7 +342,7 @@ export function div(value1: NumberSource | null | undefined, ...value2: (NumberS
345
342
  *
346
343
  * @param {NumberSource | null | undefined} value
347
344
  * @param {number} scale
348
- * @param {RoundingMode} roundingMode
345
+ * @param {RoundingMode} [roundingMode] デフォルトは 1: 四捨五入
349
346
  * 0 切り捨て
350
347
  * 1 四捨五入
351
348
  * 2 ISO丸め
@@ -356,33 +353,33 @@ export function div(value1: NumberSource | null | undefined, ...value2: (NumberS
356
353
  export function round(
357
354
  value: NumberSource | null | undefined,
358
355
  scale: number,
359
- roundingMode: RoundingMode
356
+ roundingMode?: RoundingMode
360
357
  ): number | null {
361
358
  if (value == null) {
362
359
  return null;
363
360
  }
361
+ const rm = roundingMode ?? ROUNDING_MODE.roundHalfUp;
364
362
  switch (typeof value) {
365
363
  case 'number':
366
364
  if (!Number.isFinite(value)) {
367
- // Big.jsはNaN/Infinityを扱えないため
365
+ // NaN/Infinityはそのまま返す
368
366
  return value;
369
367
  }
370
- return Big(value).round(scale, roundingMode).toNumber();
368
+ return new Decimal(value).round(scale, rm).toNumber();
371
369
  case 'string': {
372
- const trimmed = value.trim();
373
- if (trimmed === '') {
370
+ if (isBlank(value)) {
374
371
  // 空文字は値なしとしてnullと同じ扱いにする
375
372
  return null;
376
373
  }
377
374
  try {
378
- return Big(trimmed).round(scale, roundingMode).toNumber();
375
+ return new Decimal(value).round(scale, rm).toNumber();
379
376
  } catch (error) {
380
- // 数値として解釈できない文字列([big.js] Invalid number)
377
+ // 数値として解釈できない文字列
381
378
  return Number.NaN;
382
379
  }
383
380
  }
384
381
  default:
385
- return toBig(value).round(scale, roundingMode).toNumber();
382
+ return new Decimal(value).round(scale, rm).toNumber();
386
383
  }
387
384
  }
388
385
 
@@ -408,70 +405,20 @@ export function toString(
408
405
  if (value == null) {
409
406
  return '';
410
407
  }
408
+ if (isBlank(value) || (typeof value === 'number' && !Number.isFinite(value))) {
409
+ // 空文字・NaN・Infinityは数値として扱わない
410
+ return String(value);
411
+ }
411
412
  try {
412
- const big = toBig(value);
413
+ const decimal = new Decimal(value);
413
414
  return options?.scale != null
414
- ? big.toFixed(options.scale, options.roundingMode ?? ROUNDING_MODE.roundHalfUp)
415
- : big.toFixed();
415
+ ? decimal.toFixed(options.scale, options.roundingMode ?? ROUNDING_MODE.roundHalfUp)
416
+ : decimal.toString();
416
417
  } catch (error) {
417
418
  return String(value);
418
419
  }
419
420
  }
420
421
 
421
- /**
422
- * 数値型をビットの配列に変換する
423
- * 例)
424
- * 7 => [1, 2, 4]
425
- *
426
- * 第二引数に候補値の配列を渡した場合、対象リストの中から該当するもののうち、値の大きなものから抽出して配列で返す
427
- * 例)
428
- * 86, [2, 4, 80] => [2, 4, 80]
429
- * この例で第二引数を渡さない場合は 86 => [2, 4, 16, 64] になる
430
- * 候補値はそのビットがすべて立っている場合のみ該当とする(16, [80] => [])
431
- * いずれの候補値にも分類できないビットは無視される
432
- * 小数は切り捨て、0以下は空配列を返す
433
- *
434
- * @param {number} a
435
- * @param {(number | string)[]} [candidates]
436
- * @returns {number[]}
437
- */
438
- export function bitArray(a: number, candidates?: (number | string)[]): number[] {
439
- const array: number[] = [];
440
- const integer = Math.trunc(a);
441
- if (!Number.isFinite(integer) || integer < 1) {
442
- return array;
443
- }
444
- // ビット演算子は値を32bit整数に切り詰めるため、2^32以上で判定が狂い無限ループになる。BigIntで演算する
445
- let val = BigInt(integer);
446
- if (candidates) {
447
- const cloneArray = candidates.map(a => Number(a)).filter(a => Number.isInteger(a) && 0 < a);
448
- cloneArray.sort((a: number, b: number) => {
449
- return b - a;
450
- });
451
- for (const clone of cloneArray) {
452
- const bits = BigInt(clone);
453
- if ((val & bits) === bits) {
454
- array.push(clone);
455
- val -= bits;
456
- }
457
- }
458
- array.sort((a: number, b: number) => {
459
- return a - b;
460
- });
461
- } else {
462
- const zero = BigInt(0);
463
- let bit = BigInt(1);
464
- while (zero < val) {
465
- if ((val & bit) !== zero) {
466
- array.push(Number(bit));
467
- val -= bit;
468
- }
469
- bit *= BigInt(2);
470
- }
471
- }
472
- return array;
473
- }
474
-
475
422
  /**
476
423
  * 渡されたバイト数値を桁数に応じてMB,GBなどに単位を変更する
477
424
  *
@@ -493,18 +440,18 @@ export function formatBytes(
493
440
  if (bytes == null || bytes === '') {
494
441
  return [String(bytes), ''];
495
442
  }
496
- let bigValue: Big;
443
+ let decimalValue: Decimal;
497
444
  switch (typeof bytes) {
498
445
  case 'number':
499
446
  if (Number.isNaN(bytes)) {
500
447
  // "NaN" を返却
501
448
  return ['NaN', ''];
502
449
  }
503
- bigValue = Big(bytes);
450
+ decimalValue = new Decimal(bytes);
504
451
  break;
505
452
  case 'string':
506
453
  try {
507
- bigValue = Big(removeComma(bytes));
454
+ decimalValue = new Decimal(removeComma(bytes));
508
455
  } catch (error) {
509
456
  // 元の文字列を返却
510
457
  return [bytes, ''];
@@ -512,18 +459,18 @@ export function formatBytes(
512
459
  break;
513
460
  default:
514
461
  // bigintの場合
515
- bigValue = toBig(bytes);
462
+ decimalValue = new Decimal(bytes);
516
463
  }
517
464
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
518
465
  let i = 0;
519
- while (bigValue.gte(1024) && i < units.length - 1) {
520
- bigValue = bigValue.div(1024);
466
+ while (decimalValue.gte(1024) && i < units.length - 1) {
467
+ decimalValue = decimalValue.div(1024);
521
468
  i++;
522
469
  }
523
470
  const scale = options?.scale ?? 2;
524
471
  const roundingMode = options?.roundingMode ?? ROUNDING_MODE.roundHalfUp;
525
472
  if (options?.format) {
526
- return [formatComma(bigValue.toFixed(), scale, roundingMode), units[i]];
473
+ return [formatComma(decimalValue.toString(), scale, roundingMode), units[i]];
527
474
  }
528
- return [bigValue.round(scale, roundingMode).toString(), units[i]];
475
+ return [decimalValue.round(scale, roundingMode).toString(), units[i]];
529
476
  }