@arki/money 0.0.0-stage → 0.0.4
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/LICENSE +21 -0
- package/README.md +238 -2
- package/dist/bag.d.ts +48 -0
- package/dist/bag.d.ts.map +1 -0
- package/dist/bag.js +110 -0
- package/dist/bag.js.map +1 -0
- package/dist/currency.d.ts +64 -0
- package/dist/currency.d.ts.map +1 -0
- package/dist/currency.js +148 -0
- package/dist/currency.js.map +1 -0
- package/dist/data/iso4217.d.ts +9 -0
- package/dist/data/iso4217.d.ts.map +1 -0
- package/dist/data/iso4217.js +11 -0
- package/dist/data/iso4217.js.map +1 -0
- package/dist/drizzle/config.d.ts +27 -0
- package/dist/drizzle/config.d.ts.map +1 -0
- package/dist/drizzle/config.js +16 -0
- package/dist/drizzle/config.js.map +1 -0
- package/dist/drizzle/mysql.d.ts +36 -0
- package/dist/drizzle/mysql.d.ts.map +1 -0
- package/dist/drizzle/mysql.js +45 -0
- package/dist/drizzle/mysql.js.map +1 -0
- package/dist/drizzle/pg.d.ts +38 -0
- package/dist/drizzle/pg.d.ts.map +1 -0
- package/dist/drizzle/pg.js +49 -0
- package/dist/drizzle/pg.js.map +1 -0
- package/dist/drizzle/sqlite.d.ts +38 -0
- package/dist/drizzle/sqlite.d.ts.map +1 -0
- package/dist/drizzle/sqlite.js +45 -0
- package/dist/drizzle/sqlite.js.map +1 -0
- package/dist/drizzle.d.ts +56 -0
- package/dist/drizzle.d.ts.map +1 -0
- package/dist/drizzle.js +77 -0
- package/dist/drizzle.js.map +1 -0
- package/dist/errors.d.ts +32 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +42 -0
- package/dist/errors.js.map +1 -0
- package/dist/exact.d.ts +20 -0
- package/dist/exact.d.ts.map +1 -0
- package/dist/exact.js +23 -0
- package/dist/exact.js.map +1 -0
- package/dist/exchange.d.ts +84 -0
- package/dist/exchange.d.ts.map +1 -0
- package/dist/exchange.js +215 -0
- package/dist/exchange.js.map +1 -0
- package/dist/format.d.ts +41 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +122 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/columns.d.ts +25 -0
- package/dist/internal/columns.d.ts.map +1 -0
- package/dist/internal/columns.js +47 -0
- package/dist/internal/columns.js.map +1 -0
- package/dist/internal/units.d.ts +66 -0
- package/dist/internal/units.d.ts.map +1 -0
- package/dist/internal/units.js +205 -0
- package/dist/internal/units.js.map +1 -0
- package/dist/money.d.ts +180 -0
- package/dist/money.d.ts.map +1 -0
- package/dist/money.js +577 -0
- package/dist/money.js.map +1 -0
- package/dist/parse.d.ts +53 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +222 -0
- package/dist/parse.js.map +1 -0
- package/dist/provider.d.ts +22 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +56 -0
- package/dist/provider.js.map +1 -0
- package/dist/rational.d.ts +67 -0
- package/dist/rational.d.ts.map +1 -0
- package/dist/rational.js +169 -0
- package/dist/rational.js.map +1 -0
- package/dist/stripe.d.ts +37 -0
- package/dist/stripe.d.ts.map +1 -0
- package/dist/stripe.js +75 -0
- package/dist/stripe.js.map +1 -0
- package/dist/zod.d.ts +54 -0
- package/dist/zod.d.ts.map +1 -0
- package/dist/zod.js +96 -0
- package/dist/zod.js.map +1 -0
- package/package.json +137 -4
- package/src/bag.ts +128 -0
- package/src/currency.ts +174 -0
- package/src/data/iso4217.ts +13 -0
- package/src/drizzle/config.ts +39 -0
- package/src/drizzle/mysql.ts +61 -0
- package/src/drizzle/pg.ts +64 -0
- package/src/drizzle/sqlite.ts +61 -0
- package/src/errors.ts +61 -0
- package/src/exact.ts +29 -0
- package/src/exchange.ts +280 -0
- package/src/format.ts +148 -0
- package/src/index.ts +16 -0
- package/src/internal/columns.ts +74 -0
- package/src/internal/units.ts +223 -0
- package/src/money.ts +692 -0
- package/src/parse.ts +278 -0
- package/src/provider.ts +67 -0
- package/src/rational.ts +214 -0
- package/src/stripe.ts +84 -0
- package/src/zod.ts +123 -0
package/dist/format.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Localized display through `Intl.NumberFormat`. The amount reaches `Intl` as
|
|
3
|
+
* exact decimal text, never as a float, so digits past 2^53 survive on runtimes
|
|
4
|
+
* that support string input (ES2023). Where a runtime lacks a feature you asked
|
|
5
|
+
* for (React Native's Hermes on iOS lacks some), the call throws
|
|
6
|
+
* `UnsupportedFeatureError` instead of quietly printing something else.
|
|
7
|
+
*
|
|
8
|
+
* Rounding for display is done exactly by this package, not by `Intl`, so it
|
|
9
|
+
* matches arithmetic rounding everywhere.
|
|
10
|
+
*/
|
|
11
|
+
import { UnsupportedFeatureError } from '@arki/math/errors';
|
|
12
|
+
const CACHE_LIMIT = 64;
|
|
13
|
+
const cache = new Map();
|
|
14
|
+
let exactStrings;
|
|
15
|
+
function isNumericText(text) {
|
|
16
|
+
return /^-?\d+(?:\.\d+)?$/.test(text);
|
|
17
|
+
}
|
|
18
|
+
/** Whether `format('9007199254740993')` keeps every digit (ES2023 string input). */
|
|
19
|
+
function supportsExactStrings() {
|
|
20
|
+
if (exactStrings === undefined) {
|
|
21
|
+
try {
|
|
22
|
+
exactStrings =
|
|
23
|
+
new Intl.NumberFormat('en-US', { useGrouping: false, maximumFractionDigits: 0 }).format('9007199254740993') ===
|
|
24
|
+
'9007199254740993';
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
exactStrings = false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return exactStrings;
|
|
31
|
+
}
|
|
32
|
+
function formatterFor(money, options, digits) {
|
|
33
|
+
const currency = money.currency;
|
|
34
|
+
const locale = options.locale ?? 'en-US';
|
|
35
|
+
const display = options.display ?? (currency.iso ? 'symbol' : 'code');
|
|
36
|
+
if (!currency.iso && display !== 'code') {
|
|
37
|
+
throw new UnsupportedFeatureError(`${currency.code} is a custom currency; only display: 'code' is available`);
|
|
38
|
+
}
|
|
39
|
+
const key = `${locale}|${currency.iso ? currency.code : ''}|${display}|${options.accounting === true ? 1 : 0}|${options.signDisplay ?? ''}|${options.useGrouping === false ? 0 : 1}|${digits}`;
|
|
40
|
+
const cached = cache.get(key);
|
|
41
|
+
if (cached !== undefined)
|
|
42
|
+
return cached;
|
|
43
|
+
const intlOptions = {
|
|
44
|
+
minimumFractionDigits: digits,
|
|
45
|
+
maximumFractionDigits: digits,
|
|
46
|
+
useGrouping: options.useGrouping !== false,
|
|
47
|
+
};
|
|
48
|
+
if (currency.iso) {
|
|
49
|
+
intlOptions.style = 'currency';
|
|
50
|
+
intlOptions.currency = currency.code;
|
|
51
|
+
intlOptions.currencyDisplay = display;
|
|
52
|
+
if (options.accounting === true)
|
|
53
|
+
intlOptions.currencySign = 'accounting';
|
|
54
|
+
}
|
|
55
|
+
if (options.signDisplay !== undefined)
|
|
56
|
+
intlOptions.signDisplay = options.signDisplay;
|
|
57
|
+
let formatter;
|
|
58
|
+
try {
|
|
59
|
+
formatter = new Intl.NumberFormat(locale, intlOptions);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
throw new UnsupportedFeatureError(`This runtime's Intl cannot format with these options`, { cause: error });
|
|
63
|
+
}
|
|
64
|
+
const resolved = formatter.resolvedOptions();
|
|
65
|
+
if (options.accounting === true && resolved.currencySign !== 'accounting') {
|
|
66
|
+
throw new UnsupportedFeatureError('This runtime does not support accounting currency format');
|
|
67
|
+
}
|
|
68
|
+
if (options.signDisplay !== undefined && resolved.signDisplay !== options.signDisplay) {
|
|
69
|
+
throw new UnsupportedFeatureError(`This runtime does not support signDisplay: '${options.signDisplay}'`);
|
|
70
|
+
}
|
|
71
|
+
if (resolved.maximumFractionDigits !== digits) {
|
|
72
|
+
throw new UnsupportedFeatureError(`This runtime cannot show ${digits} decimals`);
|
|
73
|
+
}
|
|
74
|
+
if (cache.size >= CACHE_LIMIT)
|
|
75
|
+
cache.clear();
|
|
76
|
+
cache.set(key, formatter);
|
|
77
|
+
return formatter;
|
|
78
|
+
}
|
|
79
|
+
function prepare(money, options) {
|
|
80
|
+
const digits = options.fractionDigits ?? money.scale;
|
|
81
|
+
const shown = digits === money.scale ? money : money.toScale(digits, options.rounding);
|
|
82
|
+
const formatter = formatterFor(shown, options, digits);
|
|
83
|
+
const text = shown.toDecimalString();
|
|
84
|
+
if (!isNumericText(text))
|
|
85
|
+
throw new TypeError(`Unexpected decimal text ${text}`);
|
|
86
|
+
if (supportsExactStrings())
|
|
87
|
+
return [formatter, text];
|
|
88
|
+
// Without string input, Intl converts to a double; up to 15 significant digits survive that exactly.
|
|
89
|
+
if (text.replaceAll(/[-.]/g, '').replace(/^0+/, '').length > 15) {
|
|
90
|
+
throw new UnsupportedFeatureError('This runtime cannot format more than 15 significant digits exactly');
|
|
91
|
+
}
|
|
92
|
+
return [formatter, Number(text)];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* `formatMoney(money('1234.5', 'EUR'), { locale: 'de-DE' })` → `'1.234,50 €'`.
|
|
96
|
+
* Custom currencies print the number and the code: `'0.00012000 BTC'`.
|
|
97
|
+
*/
|
|
98
|
+
export function formatMoney(money, options = {}) {
|
|
99
|
+
const [formatter, value] = prepare(money, options);
|
|
100
|
+
const text = formatter.format(value);
|
|
101
|
+
return money.currency.iso ? text : `${text} ${money.currency.code}`;
|
|
102
|
+
}
|
|
103
|
+
/** The parts `Intl` produces (currency, integer, group, decimal, fraction, ...), for custom rendering. */
|
|
104
|
+
export function formatMoneyToParts(money, options = {}) {
|
|
105
|
+
const [formatter, value] = prepare(money, options);
|
|
106
|
+
if (typeof formatter.formatToParts !== 'function') {
|
|
107
|
+
throw new UnsupportedFeatureError('This runtime does not support Intl.NumberFormat#formatToParts');
|
|
108
|
+
}
|
|
109
|
+
const parts = formatter.formatToParts(value);
|
|
110
|
+
if (!money.currency.iso)
|
|
111
|
+
parts.push({ type: 'literal', value: ' ' }, { type: 'currency', value: money.currency.code });
|
|
112
|
+
return parts;
|
|
113
|
+
}
|
|
114
|
+
/** Binds options once for loops: `const eur = createMoneyFormatter({ locale: 'de-DE' }); eur.format(price)`. */
|
|
115
|
+
export function createMoneyFormatter(options = {}) {
|
|
116
|
+
const bound = { ...options };
|
|
117
|
+
return {
|
|
118
|
+
format: money => formatMoney(money, bound),
|
|
119
|
+
formatToParts: money => formatMoneyToParts(money, bound),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { Currency, ISO_4217_VERSION } from './currency.js';
|
|
2
|
+
export type { CurrencyDefinition, CurrencyLike } from './currency.js';
|
|
3
|
+
export { Factor, Money, average, factor, isMoney, max, min, money, sum } from './money.js';
|
|
4
|
+
export type { AllocateOptions, Amount, DecimalLike, FactorInput, MoneyJSON, MoneyOptions, RationalLike, RemainderPolicy, Units, } from './money.js';
|
|
5
|
+
export * from './errors.js';
|
|
6
|
+
export type { RoundingMode } from '@arki/math/rounding';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAC3F,YAAY,EACV,eAAe,EACf,MAAM,EACN,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,KAAK,GACN,MAAM,YAAY,CAAC;AACpB,cAAc,aAAa,CAAC;AAC5B,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE3D,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAY3F,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The value conversions behind the Drizzle columns, shared by every SQL
|
|
3
|
+
* dialect. Each dialect file only says which column type to declare.
|
|
4
|
+
*/
|
|
5
|
+
import type { Currency } from '../currency.js';
|
|
6
|
+
import type { Money } from '../money.js';
|
|
7
|
+
import type { Units } from './units.js';
|
|
8
|
+
/** What drivers hand back for an integer column. */
|
|
9
|
+
export type IntegerDriverValue = number | bigint | string;
|
|
10
|
+
/** Minor units at the column's scale, in canonical form. Throws if the value is in another currency or needs rounding. */
|
|
11
|
+
export declare function minorToDriver(value: Money, currency: Currency, scale: number): Units;
|
|
12
|
+
/**
|
|
13
|
+
* Reads an integer column. A `number` that is not a safe integer was already
|
|
14
|
+
* rounded by the driver, so it throws instead of becoming a wrong amount.
|
|
15
|
+
*/
|
|
16
|
+
export declare function minorFromDriver<C extends string>(value: IntegerDriverValue, currency: Currency<C>, scale: number): Money<C>;
|
|
17
|
+
/** Exact decimal text at the column's scale. */
|
|
18
|
+
export declare function decimalToDriver(value: Money, currency: Currency, scale: number): string;
|
|
19
|
+
/** Reads decimal text (or a driver's number for a whole value) at the column's scale. */
|
|
20
|
+
export declare function decimalFromDriver<C extends string>(value: string | number, currency: Currency<C>, scale: number): Money<C>;
|
|
21
|
+
/** `{ amount, currency }` as JSON text. */
|
|
22
|
+
export declare function jsonToDriver(value: Money): string;
|
|
23
|
+
/** Reads JSON text, or an object for drivers that parse JSON columns themselves. */
|
|
24
|
+
export declare function jsonFromDriver(value: unknown, currencies: readonly Currency[] | undefined): Money;
|
|
25
|
+
//# sourceMappingURL=columns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../src/internal/columns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAKxC,oDAAoD;AACpD,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1D,0HAA0H;AAC1H,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAGpF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,KAAK,EAAE,MAAM,GACZ,KAAK,CAAC,CAAC,CAAC,CAYV;AAED,gDAAgD;AAChD,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvF;AAED,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAChD,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,KAAK,EAAE,MAAM,GACZ,KAAK,CAAC,CAAC,CAAC,CAEV;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEjD;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,GAAG,KAAK,CAOjG"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The value conversions behind the Drizzle columns, shared by every SQL
|
|
3
|
+
* dialect. Each dialect file only says which column type to declare.
|
|
4
|
+
*/
|
|
5
|
+
import { InvalidArgumentError, NumericRangeError } from '@arki/math/errors';
|
|
6
|
+
import { assertSameCurrency, resolveCurrency } from '../currency.js';
|
|
7
|
+
import { Money as MoneyClass } from '../money.js';
|
|
8
|
+
import { quantize } from './units.js';
|
|
9
|
+
/** Minor units at the column's scale, in canonical form. Throws if the value is in another currency or needs rounding. */
|
|
10
|
+
export function minorToDriver(value, currency, scale) {
|
|
11
|
+
assertSameCurrency(value.currency, currency);
|
|
12
|
+
return quantize(value.units, value.scale, scale);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Reads an integer column. A `number` that is not a safe integer was already
|
|
16
|
+
* rounded by the driver, so it throws instead of becoming a wrong amount.
|
|
17
|
+
*/
|
|
18
|
+
export function minorFromDriver(value, currency, scale) {
|
|
19
|
+
if (typeof value === 'number' && !Number.isSafeInteger(value)) {
|
|
20
|
+
throw new NumericRangeError(`The database driver returned ${value}, which a JavaScript number cannot hold exactly; ` +
|
|
21
|
+
'configure the driver to return big integers as strings or bigint');
|
|
22
|
+
}
|
|
23
|
+
return MoneyClass.fromMinor(typeof value === 'number' || typeof value === 'bigint' ? value : String(value), currency, scale);
|
|
24
|
+
}
|
|
25
|
+
/** Exact decimal text at the column's scale. */
|
|
26
|
+
export function decimalToDriver(value, currency, scale) {
|
|
27
|
+
assertSameCurrency(value.currency, currency);
|
|
28
|
+
return value.toScale(scale).toDecimalString();
|
|
29
|
+
}
|
|
30
|
+
/** Reads decimal text (or a driver's number for a whole value) at the column's scale. */
|
|
31
|
+
export function decimalFromDriver(value, currency, scale) {
|
|
32
|
+
return MoneyClass.of(typeof value === 'number' ? value : String(value), currency, { scale });
|
|
33
|
+
}
|
|
34
|
+
/** `{ amount, currency }` as JSON text. */
|
|
35
|
+
export function jsonToDriver(value) {
|
|
36
|
+
return JSON.stringify(value.toJSON());
|
|
37
|
+
}
|
|
38
|
+
/** Reads JSON text, or an object for drivers that parse JSON columns themselves. */
|
|
39
|
+
export function jsonFromDriver(value, currencies) {
|
|
40
|
+
const parsed = typeof value === 'string' ? JSON.parse(value) : value;
|
|
41
|
+
if (typeof parsed !== 'object' || parsed === null || !('currency' in parsed) || typeof parsed.currency !== 'string') {
|
|
42
|
+
throw new InvalidArgumentError('A money JSON column holds { amount, currency }');
|
|
43
|
+
}
|
|
44
|
+
resolveCurrency(parsed.currency, currencies);
|
|
45
|
+
return MoneyClass.fromJSON(parsed, currencies);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=columns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columns.js","sourceRoot":"","sources":["../../src/internal/columns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAK5E,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKtC,0HAA0H;AAC1H,MAAM,UAAU,aAAa,CAAC,KAAY,EAAE,QAAkB,EAAE,KAAa;IAC3E,kBAAkB,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7C,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAyB,EACzB,QAAqB,EACrB,KAAa;IAEb,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,iBAAiB,CACzB,gCAAgC,KAAK,mDAAmD;YACtF,kEAAkE,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC,SAAS,CACzB,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC9E,QAAQ,EACR,KAAK,CACN,CAAC;AACJ,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,eAAe,CAAC,KAAY,EAAE,QAAkB,EAAE,KAAa;IAC7E,kBAAkB,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,CAAC;AAChD,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,iBAAiB,CAC/B,KAAsB,EACtB,QAAqB,EACrB,KAAa;IAEb,OAAO,UAAU,CAAC,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,YAAY,CAAC,KAAY;IACvC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,UAA2C;IACxF,MAAM,MAAM,GAAY,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9E,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACpH,MAAM,IAAI,oBAAoB,CAAC,gDAAgD,CAAC,CAAC;IACnF,CAAC;IACD,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC7C,OAAO,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whole-unit arithmetic. An amount is a count of whole units, held as a plain
|
|
3
|
+
* `number` while it is a safe integer and as a `bigint` beyond that. Each value
|
|
4
|
+
* has exactly one of the two forms ("canonical form"): a `number` if and only
|
|
5
|
+
* if it is a safe integer, never `-0`.
|
|
6
|
+
*
|
|
7
|
+
* Plain numbers are several times faster than `bigint` on every engine, and
|
|
8
|
+
* 2^53 cents is 90 trillion in a two-decimal currency, so almost every program
|
|
9
|
+
* stays on the number path. The `bigint` path keeps the rest exact.
|
|
10
|
+
*/
|
|
11
|
+
import type { RoundingMode } from '@arki/math/rounding';
|
|
12
|
+
export type Units = number | bigint;
|
|
13
|
+
/** Largest number of decimals a `Money` or a custom currency may have. */
|
|
14
|
+
export declare const MAX_SCALE = 100;
|
|
15
|
+
/** Longest amount string that is parsed. */
|
|
16
|
+
export declare const MAX_INPUT_LENGTH = 1000;
|
|
17
|
+
/** Largest number of parts `allocate` and `split` produce. */
|
|
18
|
+
export declare const MAX_PARTS = 10000;
|
|
19
|
+
/** Brings a `bigint` to canonical form. */
|
|
20
|
+
export declare function canon(value: bigint): Units;
|
|
21
|
+
/** `10^exponent` in canonical form. `exponent` is a small non-negative integer. */
|
|
22
|
+
export declare function pow10(exponent: number): Units;
|
|
23
|
+
/** Exact sum. */
|
|
24
|
+
export declare function addUnits(a: Units, b: Units): Units;
|
|
25
|
+
/** Exact product. */
|
|
26
|
+
export declare function mulUnits(a: Units, b: Units): Units;
|
|
27
|
+
export declare function negUnits(a: Units): Units;
|
|
28
|
+
/** `-1`, `0` or `1`. Mixed `number`/`bigint` comparison is exact in JavaScript. */
|
|
29
|
+
export declare function compareUnits(a: Units, b: Units): -1 | 0 | 1;
|
|
30
|
+
/**
|
|
31
|
+
* `units × numerator ÷ denominator` as a whole number, rounded with `mode`.
|
|
32
|
+
* `denominator` must be positive. With no mode (or `'unnecessary'`) an inexact
|
|
33
|
+
* result throws `RoundingNecessaryError`. Every operation that can lose digits
|
|
34
|
+
* reduces to this call.
|
|
35
|
+
*/
|
|
36
|
+
export declare function mulDiv(units: Units, numerator: Units, denominator: Units, mode?: RoundingMode): Units;
|
|
37
|
+
/**
|
|
38
|
+
* Brings `coefficient × 10^-fraction` onto the grid of `scale` decimals, and
|
|
39
|
+
* onto multiples of `step` units when a step is given. Rounds once, never
|
|
40
|
+
* first to the scale and then to the step.
|
|
41
|
+
*/
|
|
42
|
+
export declare function quantize(coefficient: Units, fraction: number, scale: number, mode?: RoundingMode, step?: Units): Units;
|
|
43
|
+
/** A decimal read from text: `coefficient × 10^-fraction`, with `fraction >= 0`. */
|
|
44
|
+
export type Parsed = {
|
|
45
|
+
coefficient: Units;
|
|
46
|
+
fraction: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Reads plain decimal text: an optional sign, digits, an optional fraction, an
|
|
50
|
+
* optional exponent. No grouping, no spaces, no `Infinity`. Throws
|
|
51
|
+
* `NumberFormatError` otherwise.
|
|
52
|
+
*/
|
|
53
|
+
export declare function parseDecimal(text: string): Parsed;
|
|
54
|
+
/**
|
|
55
|
+
* Reads a JS number through its shortest decimal spelling, so `19.99` means
|
|
56
|
+
* exactly 19.99 — what was typed, not the binary approximation. It cannot undo
|
|
57
|
+
* earlier float arithmetic: `0.1 + 0.2` arrives as `0.30000000000000004`.
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseNumber(value: number): Parsed;
|
|
60
|
+
/** Throws `DivisionByZeroError` for a zero divisor. */
|
|
61
|
+
export declare function assertNonZero(value: Units): void;
|
|
62
|
+
/** Greatest common divisor of two non-negative values, in canonical form. */
|
|
63
|
+
export declare function gcdUnits(a: Units, b: Units): Units;
|
|
64
|
+
/** `a / b` for a `b` known to divide `a` exactly. */
|
|
65
|
+
export declare function divExact(a: Units, b: Units): Units;
|
|
66
|
+
//# sourceMappingURL=units.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"units.d.ts","sourceRoot":"","sources":["../../src/internal/units.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AASxD,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAKpC,0EAA0E;AAC1E,eAAO,MAAM,SAAS,MAAM,CAAC;AAC7B,4CAA4C;AAC5C,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,8DAA8D;AAC9D,eAAO,MAAM,SAAS,QAAS,CAAC;AAIhC,2CAA2C;AAC3C,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAE1C;AAED,mFAAmF;AACnF,wBAAgB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAE7C;AAED,iBAAiB;AACjB,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAOlD;AAED,qBAAqB;AACrB,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAQlD;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAExC;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAE3D;AA2BD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,KAAK,CAuBrG;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,WAAW,EAAE,KAAK,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,YAAY,EACnB,IAAI,CAAC,EAAE,KAAK,GACX,KAAK,CASP;AAED,oFAAoF;AACpF,MAAM,MAAM,MAAM,GAAG;IAAE,WAAW,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAI9D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmBjD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASjD;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAEhD;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAWlD;AAED,qDAAqD;AACrD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAGlD"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whole-unit arithmetic. An amount is a count of whole units, held as a plain
|
|
3
|
+
* `number` while it is a safe integer and as a `bigint` beyond that. Each value
|
|
4
|
+
* has exactly one of the two forms ("canonical form"): a `number` if and only
|
|
5
|
+
* if it is a safe integer, never `-0`.
|
|
6
|
+
*
|
|
7
|
+
* Plain numbers are several times faster than `bigint` on every engine, and
|
|
8
|
+
* 2^53 cents is 90 trillion in a two-decimal currency, so almost every program
|
|
9
|
+
* stays on the number path. The `bigint` path keeps the rest exact.
|
|
10
|
+
*/
|
|
11
|
+
import { DivisionByZeroError, NumberFormatError, NumericRangeError, ResourceLimitError, RoundingNecessaryError, } from '@arki/math/errors';
|
|
12
|
+
const MAX = Number.MAX_SAFE_INTEGER;
|
|
13
|
+
const MAX_BIG = BigInt(Number.MAX_SAFE_INTEGER);
|
|
14
|
+
/** Largest number of decimals a `Money` or a custom currency may have. */
|
|
15
|
+
export const MAX_SCALE = 100;
|
|
16
|
+
/** Longest amount string that is parsed. */
|
|
17
|
+
export const MAX_INPUT_LENGTH = 1000;
|
|
18
|
+
/** Largest number of parts `allocate` and `split` produce. */
|
|
19
|
+
export const MAX_PARTS = 10_000;
|
|
20
|
+
const POW10 = [1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15];
|
|
21
|
+
/** Brings a `bigint` to canonical form. */
|
|
22
|
+
export function canon(value) {
|
|
23
|
+
return value >= -MAX_BIG && value <= MAX_BIG ? Number(value) : value;
|
|
24
|
+
}
|
|
25
|
+
/** `10^exponent` in canonical form. `exponent` is a small non-negative integer. */
|
|
26
|
+
export function pow10(exponent) {
|
|
27
|
+
return POW10[exponent] ?? 10n ** BigInt(exponent);
|
|
28
|
+
}
|
|
29
|
+
/** Exact sum. */
|
|
30
|
+
export function addUnits(a, b) {
|
|
31
|
+
if (typeof a === 'number' && typeof b === 'number') {
|
|
32
|
+
const sum = a + b;
|
|
33
|
+
// Two safe integers add exactly whenever the true sum is itself safe.
|
|
34
|
+
if (sum <= MAX && sum >= -MAX)
|
|
35
|
+
return sum;
|
|
36
|
+
}
|
|
37
|
+
return canon(BigInt(a) + BigInt(b));
|
|
38
|
+
}
|
|
39
|
+
/** Exact product. */
|
|
40
|
+
export function mulUnits(a, b) {
|
|
41
|
+
if (typeof a === 'number' && typeof b === 'number') {
|
|
42
|
+
const product = a * b;
|
|
43
|
+
// Float rounding never moves a value across 2^53, so a product that reads
|
|
44
|
+
// as safe is the exact product. `+ 0` turns `-0` into `0`.
|
|
45
|
+
if (product <= MAX && product >= -MAX)
|
|
46
|
+
return product + 0;
|
|
47
|
+
}
|
|
48
|
+
return canon(BigInt(a) * BigInt(b));
|
|
49
|
+
}
|
|
50
|
+
export function negUnits(a) {
|
|
51
|
+
return typeof a === 'number' ? 0 - a : -a;
|
|
52
|
+
}
|
|
53
|
+
/** `-1`, `0` or `1`. Mixed `number`/`bigint` comparison is exact in JavaScript. */
|
|
54
|
+
export function compareUnits(a, b) {
|
|
55
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The one rounding decision in the package. Given a truncated quotient, says
|
|
59
|
+
* whether to step one further away from zero.
|
|
60
|
+
*
|
|
61
|
+
* `half` compares the dropped remainder with half the divisor: `-1` below,
|
|
62
|
+
* `0` exactly half, `1` above. `odd` is whether the truncated quotient is odd.
|
|
63
|
+
*/
|
|
64
|
+
function roundsAway(mode, negative, half, odd) {
|
|
65
|
+
if (mode === 'halfEven')
|
|
66
|
+
return half > 0 || (half === 0 && odd);
|
|
67
|
+
if (mode === 'halfUp')
|
|
68
|
+
return half >= 0;
|
|
69
|
+
if (mode === 'halfDown')
|
|
70
|
+
return half > 0;
|
|
71
|
+
if (mode === 'down')
|
|
72
|
+
return false;
|
|
73
|
+
if (mode === 'up')
|
|
74
|
+
return true;
|
|
75
|
+
if (mode === 'ceiling')
|
|
76
|
+
return !negative;
|
|
77
|
+
if (mode === 'floor')
|
|
78
|
+
return negative;
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- plain JavaScript can pass a misspelled mode
|
|
80
|
+
if (mode === undefined || mode === 'unnecessary') {
|
|
81
|
+
throw new RoundingNecessaryError('The exact result does not fit the requested precision; pass a rounding mode such as "halfEven"');
|
|
82
|
+
}
|
|
83
|
+
// Reached only from plain JavaScript with a misspelled mode.
|
|
84
|
+
throw new TypeError(`Unknown rounding mode: ${String(mode)}`);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* `units × numerator ÷ denominator` as a whole number, rounded with `mode`.
|
|
88
|
+
* `denominator` must be positive. With no mode (or `'unnecessary'`) an inexact
|
|
89
|
+
* result throws `RoundingNecessaryError`. Every operation that can lose digits
|
|
90
|
+
* reduces to this call.
|
|
91
|
+
*/
|
|
92
|
+
export function mulDiv(units, numerator, denominator, mode) {
|
|
93
|
+
if (typeof units === 'number' && typeof numerator === 'number' && typeof denominator === 'number') {
|
|
94
|
+
const product = units * numerator;
|
|
95
|
+
if (product <= MAX && product >= -MAX) {
|
|
96
|
+
// `%` on doubles is exact, so both the remainder and the quotient are.
|
|
97
|
+
const remainder = product % denominator;
|
|
98
|
+
if (remainder === 0)
|
|
99
|
+
return product / denominator + 0;
|
|
100
|
+
const quotient = (product - remainder) / denominator;
|
|
101
|
+
const twice = (remainder < 0 ? -remainder : remainder) * 2;
|
|
102
|
+
const half = twice > denominator ? 1 : twice < denominator ? -1 : 0;
|
|
103
|
+
if (!roundsAway(mode, product < 0, half, quotient % 2 !== 0))
|
|
104
|
+
return quotient;
|
|
105
|
+
return product < 0 ? quotient - 1 : quotient + 1;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const product = BigInt(units) * BigInt(numerator);
|
|
109
|
+
const divisor = BigInt(denominator);
|
|
110
|
+
const quotient = product / divisor;
|
|
111
|
+
const remainder = product - quotient * divisor;
|
|
112
|
+
if (remainder === 0n)
|
|
113
|
+
return canon(quotient);
|
|
114
|
+
const twice = (remainder < 0n ? -remainder : remainder) * 2n;
|
|
115
|
+
const half = twice > divisor ? 1 : twice < divisor ? -1 : 0;
|
|
116
|
+
if (!roundsAway(mode, product < 0n, half, (quotient & 1n) !== 0n))
|
|
117
|
+
return canon(quotient);
|
|
118
|
+
return canon(product < 0n ? quotient - 1n : quotient + 1n);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Brings `coefficient × 10^-fraction` onto the grid of `scale` decimals, and
|
|
122
|
+
* onto multiples of `step` units when a step is given. Rounds once, never
|
|
123
|
+
* first to the scale and then to the step.
|
|
124
|
+
*/
|
|
125
|
+
export function quantize(coefficient, fraction, scale, mode, step) {
|
|
126
|
+
if (step === undefined) {
|
|
127
|
+
if (fraction === scale)
|
|
128
|
+
return coefficient;
|
|
129
|
+
if (fraction < scale)
|
|
130
|
+
return mulUnits(coefficient, pow10(scale - fraction));
|
|
131
|
+
return mulDiv(coefficient, 1, pow10(fraction - scale), mode);
|
|
132
|
+
}
|
|
133
|
+
const up = fraction < scale ? pow10(scale - fraction) : 1;
|
|
134
|
+
const down = fraction > scale ? pow10(fraction - scale) : 1;
|
|
135
|
+
return mulUnits(mulDiv(coefficient, up, mulUnits(down, step), mode), step);
|
|
136
|
+
}
|
|
137
|
+
const DECIMAL = /^([+-]?)(\d+)(?:\.(\d+))?(?:e([+-]?\d{1,4}))?$/i;
|
|
138
|
+
/**
|
|
139
|
+
* Reads plain decimal text: an optional sign, digits, an optional fraction, an
|
|
140
|
+
* optional exponent. No grouping, no spaces, no `Infinity`. Throws
|
|
141
|
+
* `NumberFormatError` otherwise.
|
|
142
|
+
*/
|
|
143
|
+
export function parseDecimal(text) {
|
|
144
|
+
if (text.length > MAX_INPUT_LENGTH) {
|
|
145
|
+
throw new ResourceLimitError(`Amount text is longer than ${MAX_INPUT_LENGTH} characters`);
|
|
146
|
+
}
|
|
147
|
+
const match = DECIMAL.exec(text);
|
|
148
|
+
if (match === null) {
|
|
149
|
+
throw new NumberFormatError(`${JSON.stringify(text.slice(0, 40))} is not a decimal number such as "19.99"`);
|
|
150
|
+
}
|
|
151
|
+
const whole = match[2] ?? '';
|
|
152
|
+
const fractionDigits = match[3] ?? '';
|
|
153
|
+
const digits = whole + fractionDigits;
|
|
154
|
+
const magnitude = digits.length <= 15 ? Number(digits) : canon(BigInt(digits));
|
|
155
|
+
const coefficient = match[1] === '-' ? negUnits(magnitude) : magnitude;
|
|
156
|
+
const fraction = fractionDigits.length - (match[4] === undefined ? 0 : Number(match[4]));
|
|
157
|
+
if (fraction > MAX_INPUT_LENGTH || fraction < -MAX_INPUT_LENGTH) {
|
|
158
|
+
throw new ResourceLimitError(`The exponent in ${JSON.stringify(text.slice(0, 40))} is too large`);
|
|
159
|
+
}
|
|
160
|
+
if (fraction >= 0)
|
|
161
|
+
return { coefficient, fraction };
|
|
162
|
+
return { coefficient: mulUnits(coefficient, pow10(-fraction)), fraction: 0 };
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Reads a JS number through its shortest decimal spelling, so `19.99` means
|
|
166
|
+
* exactly 19.99 — what was typed, not the binary approximation. It cannot undo
|
|
167
|
+
* earlier float arithmetic: `0.1 + 0.2` arrives as `0.30000000000000004`.
|
|
168
|
+
*/
|
|
169
|
+
export function parseNumber(value) {
|
|
170
|
+
if (Number.isSafeInteger(value))
|
|
171
|
+
return { coefficient: value + 0, fraction: 0 };
|
|
172
|
+
if (!Number.isFinite(value))
|
|
173
|
+
throw new NumericRangeError(`${value} is not a finite number`);
|
|
174
|
+
if (Number.isInteger(value)) {
|
|
175
|
+
throw new NumericRangeError(`${value} is not a safe integer; its digits are already lost. Pass a string or bigint instead`);
|
|
176
|
+
}
|
|
177
|
+
return parseDecimal(String(value));
|
|
178
|
+
}
|
|
179
|
+
/** Throws `DivisionByZeroError` for a zero divisor. */
|
|
180
|
+
export function assertNonZero(value) {
|
|
181
|
+
if (value === 0 || value === 0n)
|
|
182
|
+
throw new DivisionByZeroError('Division by zero');
|
|
183
|
+
}
|
|
184
|
+
/** Greatest common divisor of two non-negative values, in canonical form. */
|
|
185
|
+
export function gcdUnits(a, b) {
|
|
186
|
+
if (typeof a === 'number' && typeof b === 'number') {
|
|
187
|
+
let x = a;
|
|
188
|
+
let y = b;
|
|
189
|
+
while (y !== 0)
|
|
190
|
+
[x, y] = [y, x % y];
|
|
191
|
+
return x;
|
|
192
|
+
}
|
|
193
|
+
let x = BigInt(a);
|
|
194
|
+
let y = BigInt(b);
|
|
195
|
+
while (y !== 0n)
|
|
196
|
+
[x, y] = [y, x % y];
|
|
197
|
+
return canon(x);
|
|
198
|
+
}
|
|
199
|
+
/** `a / b` for a `b` known to divide `a` exactly. */
|
|
200
|
+
export function divExact(a, b) {
|
|
201
|
+
if (typeof a === 'number' && typeof b === 'number')
|
|
202
|
+
return a / b + 0;
|
|
203
|
+
return canon(BigInt(a) / BigInt(b));
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=units.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"units.js","sourceRoot":"","sources":["../../src/internal/units.ts"],"names":[],"mappings":"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"}
|