@digitalwalletcorp/utils 0.1.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.
- package/README.md +13 -12
- package/lib/crypto-util-DFJqfmuw.js +46 -0
- package/lib/crypto-util-DFJqfmuw.js.map +1 -0
- package/lib/crypto-util-DeZSGetI.cjs +2 -0
- package/lib/crypto-util-DeZSGetI.cjs.map +1 -0
- package/lib/crypto-util.cjs +2 -0
- package/lib/crypto-util.cjs.map +1 -0
- package/lib/crypto-util.d.cts +28 -0
- package/lib/crypto-util.d.ts +28 -0
- package/lib/crypto-util.js +7 -0
- package/lib/crypto-util.js.map +1 -0
- package/lib/date-util-CG7L8nSP.js +184 -0
- package/lib/date-util-CG7L8nSP.js.map +1 -0
- package/lib/date-util-DopNKy3u.cjs +2 -0
- package/lib/date-util-DopNKy3u.cjs.map +1 -0
- package/lib/date-util.cjs +2 -0
- package/lib/date-util.cjs.map +1 -0
- package/lib/date-util.d.cts +231 -0
- package/lib/date-util.d.ts +231 -0
- package/lib/date-util.js +23 -0
- package/lib/date-util.js.map +1 -0
- package/lib/decimal.cjs +2 -0
- package/lib/decimal.cjs.map +1 -0
- package/lib/decimal.d.cts +197 -0
- package/lib/decimal.d.ts +197 -0
- package/lib/decimal.js +227 -0
- package/lib/decimal.js.map +1 -0
- package/lib/file-util-D09BvDYY.cjs +2 -0
- package/lib/file-util-D09BvDYY.cjs.map +1 -0
- package/lib/file-util-H-c_eQcd.js +140 -0
- package/lib/file-util-H-c_eQcd.js.map +1 -0
- package/lib/file-util.cjs +2 -0
- package/lib/file-util.cjs.map +1 -0
- package/lib/file-util.d.cts +119 -0
- package/lib/file-util.d.ts +119 -0
- package/lib/file-util.js +18 -0
- package/lib/file-util.js.map +1 -0
- package/lib/html-util-Bxn5YDSK.cjs +2 -0
- package/lib/html-util-Bxn5YDSK.cjs.map +1 -0
- package/lib/html-util-CgMIuOsf.js +49 -0
- package/lib/html-util-CgMIuOsf.js.map +1 -0
- package/lib/html-util.cjs +2 -0
- package/lib/html-util.cjs.map +1 -0
- package/lib/html-util.d.cts +71 -0
- package/lib/html-util.d.ts +71 -0
- package/lib/html-util.js +8 -0
- package/lib/html-util.js.map +1 -0
- package/lib/index.cjs +2 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +9 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +21 -38
- package/lib/index.js.map +1 -1
- package/lib/json-util-BvrFYh5E.cjs +3 -0
- package/lib/json-util-BvrFYh5E.cjs.map +1 -0
- package/lib/json-util-YX7xSF6R.js +136 -0
- package/lib/json-util-YX7xSF6R.js.map +1 -0
- package/lib/json-util.cjs +2 -0
- package/lib/json-util.cjs.map +1 -0
- package/lib/json-util.d.cts +58 -0
- package/lib/json-util.d.ts +58 -0
- package/lib/json-util.js +8 -0
- package/lib/json-util.js.map +1 -0
- package/lib/number-util-BA4KVFyF.js +198 -0
- package/lib/number-util-BA4KVFyF.js.map +1 -0
- package/lib/number-util-BaSf1wWH.cjs +2 -0
- package/lib/number-util-BaSf1wWH.cjs.map +1 -0
- package/lib/number-util.cjs +2 -0
- package/lib/number-util.cjs.map +1 -0
- package/lib/number-util.d.cts +237 -0
- package/lib/number-util.d.ts +65 -51
- package/lib/number-util.js +23 -495
- package/lib/number-util.js.map +1 -1
- package/lib/object-util-DhGi-PmA.js +204 -0
- package/lib/object-util-DhGi-PmA.js.map +1 -0
- package/lib/object-util-Z0Ah5J8A.cjs +2 -0
- package/lib/object-util-Z0Ah5J8A.cjs.map +1 -0
- package/lib/object-util.cjs +2 -0
- package/lib/object-util.cjs.map +1 -0
- package/lib/object-util.d.cts +157 -0
- package/lib/object-util.d.ts +157 -0
- package/lib/object-util.js +16 -0
- package/lib/object-util.js.map +1 -0
- package/lib/string-util-Cw0VgbIH.js +52 -0
- package/lib/string-util-Cw0VgbIH.js.map +1 -0
- package/lib/string-util-w2I5EYuY.cjs +2 -0
- package/lib/string-util-w2I5EYuY.cjs.map +1 -0
- package/lib/string-util.cjs +2 -0
- package/lib/string-util.cjs.map +1 -0
- package/lib/string-util.d.cts +51 -0
- package/lib/string-util.d.ts +51 -0
- package/lib/string-util.js +8 -0
- package/lib/string-util.js.map +1 -0
- package/package.json +59 -16
- package/src/crypto-util.ts +84 -0
- package/src/date-util.ts +448 -0
- package/src/decimal.ts +294 -0
- package/src/file-util.ts +281 -0
- package/src/html-util.ts +196 -0
- package/src/index.ts +8 -0
- package/src/json-util.ts +271 -0
- package/src/number-util.ts +141 -194
- package/src/object-util.ts +482 -0
- package/src/string-util.ts +115 -0
package/src/number-util.ts
CHANGED
|
@@ -1,41 +1,12 @@
|
|
|
1
|
-
import {
|
|
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 =
|
|
10
|
-
const MAX_LONG =
|
|
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
|
-
|
|
47
|
-
|
|
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
|
-
|
|
67
|
-
|
|
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
|
|
41
|
+
return min.lte(value) && MAX_LONG.gte(value);
|
|
79
42
|
} catch (error) {
|
|
80
|
-
//
|
|
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以下を指数表記にするため、
|
|
108
|
-
strValue =
|
|
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
|
-
//
|
|
80
|
+
// 指数表記を通常の表記に展開する。表示用に '+' を付け直す
|
|
118
81
|
const plusSign = strValue.startsWith('+') ? '+' : '';
|
|
119
|
-
strValue = `${plusSign}${
|
|
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
|
-
|
|
132
|
-
let big = new Big(`${sign === '-' ? '-' : ''}${natural}.${decimal}`);
|
|
94
|
+
let decimalValue = new Decimal(`${sign === '-' ? '-' : ''}${natural}.${decimal}`);
|
|
133
95
|
if (scale != null) {
|
|
134
|
-
|
|
135
|
-
const roundedMatches = NUMBER_PATTERN.exec(
|
|
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 =
|
|
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
|
|
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
|
-
|
|
184
|
+
decimal = decimal.round(options.scale, options.roundingMode ?? ROUNDING_MODE.roundHalfUp);
|
|
266
185
|
}
|
|
267
|
-
return
|
|
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
|
|
199
|
+
let decimal = new Decimal(value1);
|
|
281
200
|
for (const value of value2) {
|
|
282
|
-
|
|
201
|
+
decimal = decimal.add(value);
|
|
283
202
|
}
|
|
284
|
-
return
|
|
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
|
|
216
|
+
let decimal = new Decimal(value1);
|
|
298
217
|
for (const value of value2) {
|
|
299
|
-
|
|
218
|
+
decimal = decimal.sub(value);
|
|
300
219
|
}
|
|
301
|
-
return
|
|
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
|
|
234
|
+
let decimal = new Decimal(value1);
|
|
316
235
|
for (const value of value2) {
|
|
317
|
-
|
|
236
|
+
decimal = decimal.times(value);
|
|
318
237
|
}
|
|
319
|
-
return
|
|
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
|
|
252
|
+
let decimal = new Decimal(value1);
|
|
334
253
|
for (const value of value2) {
|
|
335
|
-
|
|
254
|
+
decimal = decimal.div(value);
|
|
336
255
|
}
|
|
337
|
-
return
|
|
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
|
|
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
|
-
//
|
|
365
|
+
// NaN/Infinityはそのまま返す
|
|
368
366
|
return value;
|
|
369
367
|
}
|
|
370
|
-
return
|
|
368
|
+
return new Decimal(value).round(scale, rm).toNumber();
|
|
371
369
|
case 'string': {
|
|
372
|
-
|
|
373
|
-
if (trimmed === '') {
|
|
370
|
+
if (isBlank(value)) {
|
|
374
371
|
// 空文字は値なしとしてnullと同じ扱いにする
|
|
375
372
|
return null;
|
|
376
373
|
}
|
|
377
374
|
try {
|
|
378
|
-
return
|
|
375
|
+
return new Decimal(value).round(scale, rm).toNumber();
|
|
379
376
|
} catch (error) {
|
|
380
|
-
// 数値として解釈できない文字列
|
|
377
|
+
// 数値として解釈できない文字列
|
|
381
378
|
return Number.NaN;
|
|
382
379
|
}
|
|
383
380
|
}
|
|
384
381
|
default:
|
|
385
|
-
return
|
|
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
|
|
413
|
+
const decimal = new Decimal(value);
|
|
413
414
|
return options?.scale != null
|
|
414
|
-
?
|
|
415
|
-
:
|
|
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
|
|
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
|
-
|
|
450
|
+
decimalValue = new Decimal(bytes);
|
|
504
451
|
break;
|
|
505
452
|
case 'string':
|
|
506
453
|
try {
|
|
507
|
-
|
|
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
|
-
|
|
462
|
+
decimalValue = new Decimal(bytes);
|
|
516
463
|
}
|
|
517
464
|
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
518
465
|
let i = 0;
|
|
519
|
-
while (
|
|
520
|
-
|
|
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(
|
|
473
|
+
return [formatComma(decimalValue.toString(), scale, roundingMode), units[i]];
|
|
527
474
|
}
|
|
528
|
-
return [
|
|
475
|
+
return [decimalValue.round(scale, roundingMode).toString(), units[i]];
|
|
529
476
|
}
|