type-plus
Version:
Provides additional types for TypeScript.
1,480 lines • 35.9 kB
TypeScript
import type { Tail } from '../tuple/tail.js';
import type { PadStart } from '../tuple/tuple_plus.pad_start.js';
import type { Add as NumericAdd } from './add.js';
import type { ToNegative } from './math_plus.to_negative.js';
/**
* Internal numeric representation to perform math operations.
*
* NumericStruct: `[Type, DigitsStruct]`
* DigitsStruct: `[Sign, Digits, Exponent]`
*
* It is similar to the floating point representation with some minor differences.
*
* @template Type Type of the value, either `number` or `bigint`.
* It captures the original type of the value,
* so that at the end of the operation,
* the value can be adjusted accordingly.
*
* @template Sign Sign of the value, either `+` or `-`.
*
* @template Digits Digits of the value.
* It is a tuple of digits,
* where each digits can range from 0 to 9 during input,
* and range from -10 to 89 during operation.
* The max 89 comes from multiplication:
*
* ```
* 99 * 9
* => [[ 9, 9], 0]
* * [ [9], 0]
* => [[ 81, 81], 0]
* => [[ 89, 1], 0]
* => [[ 8, 9, 1], 0]
* ```
*
* While -10 comes from subtraction:
*
* ```
* 100 - 99 = 1
* => [[ 1, 0, 0], 0]
* - [[ 9, 9], 0]
* => [[ 1, -9, -9], 0]
* => [[ 1,-10, 1], 0] // here, as in intermediate step
* => [[ 0, 0, 1], 0]
* => [[1], 0]
* => 1
* ```
*
*
* Unlike floating point numbers, the digits length is not limited.
*
* @template Exponent Exponent is the negative exponent of the number.
*
* ```
* 1.23 = 123e^-2 = [[1, 2, 3], 2]
* 0.0123 = 123e^-4 = [[1, 2, 3], 4]
* ```
*
* There are 2 kinds of `NumericStruct`:
* - Normalized: The `NumericStruct` is clean and can be converted to/from `number` or `bigint`
* - Not normalized: The `DigitsStruct` within the `NumericStruct` is normalized,
* but may need to convert between `number` and `bigint`.\
* e.g. bigint + float => float (if possible), number + number => bigint (too big)
*
* During operations, the `DigitsStruct` can be not normalized,
* but each operation should always normalize the `DigitsStruct` before returning.
* Each operations assume the input `DigitsStruct` is normalized.
*
* All operations are performed in similar way:
*
* value -> NormalizedNumericStruct -> operation(NormalizedDigitsStruct) -> NormalizedNumericStruct -> Value
*
* This allows the operations to be composable.
* */
export type NumericStruct = ['bigint' | 'number', DigitsStruct];
export type TYPE = 0;
export type DIGITS_STRUCT = 1;
export declare namespace NumericStruct {
/**
* Creates a `NumericStruct` from number or bigint `N`.
*/
type FromNumeric<N extends number | bigint, Fail = never> = N extends number ? number extends N ? Fail : ['number', DigitsStruct.FromNumber<N>] : N extends bigint ? bigint extends N ? Fail : ['bigint', DigitsStruct.FromBigint<N>] : never;
/**
* Converts a `NumericStruct` to a number or bigint.
*
* It includes the normalization of the `NumericStruct`.
*/
type ToNumeric<M extends NumericStruct> = DigitsStruct.ToString<M[DIGITS_STRUCT]> extends infer S extends string ? M[TYPE] extends 'bigint' ? StringToBigint<S, StringToNumber<S, `The value '${S}' cannot be represented as bigint or number`>> : StringToNumber<S, StringToBigint<S, `The value '${S}' cannot be represented as bigint or number`>> : never;
type Add<A extends NumericStruct, B extends NumericStruct> = [
A[TYPE],
DigitsStruct.Add<A[DIGITS_STRUCT], B[DIGITS_STRUCT]>
];
type Subtract<A extends NumericStruct, B extends NumericStruct> = [
A[TYPE],
DigitsStruct.Subtract<A[DIGITS_STRUCT], B[DIGITS_STRUCT]>
];
type Multiply<A extends NumericStruct, B extends NumericStruct> = [
A[TYPE],
DigitsStruct.Multiply<A[DIGITS_STRUCT], B[DIGITS_STRUCT]>
];
}
type StringToBigint<S extends string, Fail> = S extends `${infer N extends bigint}` ? N : Fail;
export type StringToNumber<S extends string, Fail> = S extends `${infer N extends number}` ? number extends N ? Fail : N : Fail;
export type DigitsStruct = [Sign: '+' | '-', Digits: number[], Exponent: number];
export type SIGN = 0;
export type DIGITS = 1;
export type EXPONENT = 2;
export declare namespace DigitsStruct {
/**
* Creates a `DigitsStruct` from number `N`.
*
* @template N Number to create `DigitsStruct` from.
*/
export type FromNumber<N extends number> = `${N}` extends `-${infer R}` ? R extends `${infer W}.${infer F}` ? [DigitArray.FromString<W>, DigitArray.FromString<F>] extends [
infer WA extends number[],
infer FA extends number[]
] ? ['-', DigitArray.TrimLeadingZeros<[...WA, ...FA]>, FA['length']] : never : ['-', DigitArray.FromString<R>, 0] : `${N}` extends `${infer W}.${infer F}` ? [DigitArray.FromString<W>, DigitArray.FromString<F>] extends [
infer WA extends number[],
infer FA extends number[]
] ? ['+', DigitArray.TrimLeadingZeros<[...WA, ...FA]>, FA['length']] : never : ['+', DigitArray.FromString<`${N}`>, 0];
/**
* Creates a `DigitsStruct` from bigint `N`.
*
* @template N Number to create `DigitsStruct` from.
*/
export type FromBigint<N extends bigint> = `${N}` extends `-${infer R}` ? ['-', DigitArray.FromString<R>, 0] : ['+', DigitArray.FromString<`${N}`>, 0];
/**
* Converts a `DigitsStruct` to string.
*
* @template D A normalized `DigitsStruct`.
*/
export type ToString<D extends DigitsStruct> = (PadStart<D[DIGITS], D[EXPONENT], 0> extends infer Padded extends number[] ? Padded['length'] extends D[EXPONENT] ? DigitArray.ToString<[0, '.', ...DigitArray.TrimTrailingZeros<Padded>]> : SplitFloat<Padded, D[EXPONENT]> extends [infer W extends number[], infer F extends number[]] ? F extends [] ? DigitArray.ToString<W> : DigitArray.ToString<[...W, '.', ...DigitArray.TrimTrailingZeros<F>]> : never : never) extends infer R ? R extends '0' ? R : R extends string ? D[SIGN] extends '-' ? `-${R}` : R : never : never;
/**
* Splits DigitArray into the whole number and the fractional part.
*
* @note cannot use `ArrayPlus.SplitAt` as it causes infinite loop.
*/
type SplitFloat<A extends number[], I extends number, F extends number[] = []> = I extends 0 ? [A, []] : F['length'] extends I ? [A, F] : A extends [...infer H extends number[], infer T extends number] ? SplitFloat<H, I, [T, ...F]> : never;
/**
* Normalizes a `DigitsStruct`.
*
* The normalization two two things:
*
* - if the first digit is negative, it will flip the sign.
* - carry digits if the digit is negative or greater than 9.
*/
export type Normalize<N extends DigitsStruct, R extends DigitsStruct = ['+', [], 0]> = `${N[DIGITS][0]}` extends `-${number}` ? Normalize<FlipSign<N>, R> : [N[SIGN], DigitArray.CarryDigits<N[DIGITS]>, N[EXPONENT]];
type FlipSign<D extends DigitsStruct, I extends number[] = D[DIGITS], R extends number[] = []> = I extends [] ? D[SIGN] extends '-' ? ['+', R, D[EXPONENT]] : ['-', R, D[EXPONENT]] : I extends [infer H extends number, ...infer T extends number[]] ? FlipSign<D, T, [...R, Digit.FlipSign<H>]> : never;
/**
* Add `A` and `B`.
*
* @template A A normalized `DigitsStruct`.
* @template B B normalized `DigitsStruct`.
*/
export type Add<A extends DigitsStruct, B extends DigitsStruct> = Balance<A, B> extends [
infer BA extends DigitsStruct,
infer BB extends DigitsStruct
] ? [BA[SIGN], BB[SIGN]] extends ['+', '+'] ? Normalize<['+', DigitArray.Add<BA[DIGITS], BB[DIGITS]>, BA[EXPONENT]]> : [BA[SIGN], BB[SIGN]] extends ['+', '-'] ? Normalize<['+', DigitArray.Subtract<BA[DIGITS], BB[DIGITS]>, BA[EXPONENT]]> : [BA[SIGN], BB[SIGN]] extends ['-', '+'] ? Normalize<['+', DigitArray.Subtract<BB[DIGITS], BA[DIGITS]>, BB[EXPONENT]]> : [BA[SIGN], BB[SIGN]] extends ['-', '-'] ? Normalize<['-', DigitArray.Add<BA[DIGITS], BB[DIGITS]>, BA[EXPONENT]]> : never : never;
export type Subtract<A extends DigitsStruct, B extends DigitsStruct> = Balance<A, B> extends [
infer BA extends DigitsStruct,
infer BB extends DigitsStruct
] ? [BA[SIGN], BB[SIGN]] extends ['+', '+'] ? Normalize<['+', DigitArray.Subtract<BA[DIGITS], BB[DIGITS]>, BA[EXPONENT]]> : [BA[SIGN], BB[SIGN]] extends ['+', '-'] ? Normalize<['+', DigitArray.Add<BA[DIGITS], BB[DIGITS]>, BA[EXPONENT]]> : [BA[SIGN], BB[SIGN]] extends ['-', '+'] ? Normalize<['-', DigitArray.Add<BB[DIGITS], BA[DIGITS]>, BA[EXPONENT]]> : [BA[SIGN], BB[SIGN]] extends ['-', '-'] ? Normalize<['-', DigitArray.Subtract<BA[DIGITS], BB[DIGITS]>, BA[EXPONENT]]> : never : never;
export type Multiply<A extends DigitsStruct, B extends DigitsStruct> = NumericAdd<A[EXPONENT], B[EXPONENT]> extends infer Exp extends number ? [A[SIGN], B[SIGN]] extends ['+', '+'] ? Normalize<['+', DigitArray.Multiply<A[DIGITS], B[DIGITS]>, Exp]> : [A[SIGN], B[SIGN]] extends ['+', '-'] ? Normalize<['-', DigitArray.Multiply<A[DIGITS], B[DIGITS]>, Exp]> : [A[SIGN], B[SIGN]] extends ['-', '+'] ? Normalize<['-', DigitArray.Multiply<B[DIGITS], A[DIGITS]>, Exp]> : [A[SIGN], B[SIGN]] extends ['-', '-'] ? Normalize<['+', DigitArray.Multiply<A[DIGITS], B[DIGITS]>, Exp]> : never : never;
/**
* Balance the two structs for add/subtract.
*/
export type Balance<A extends DigitsStruct, B extends DigitsStruct> = GetBalancePadding<A[EXPONENT], B[EXPONENT]> extends [infer Pads extends number[], infer Longer] ? Longer extends 'A' ? [A, [B[SIGN], DigitArray.TrimLeadingZeros<[...B[DIGITS], ...Pads]>, A[EXPONENT]]] : [[A[SIGN], DigitArray.TrimLeadingZeros<[...A[DIGITS], ...Pads]>, B[EXPONENT]], B] : never;
type GetBalancePadding<A extends number, B extends number, C extends number[] = [], R extends number[] = []> = A extends B ? [[], 'A'] : R extends [] ? C['length'] extends A ? GetBalancePadding<A, B, [0, ...C], [0]> : C['length'] extends B ? GetBalancePadding<A, B, [0, ...C], [0, ...R]> : GetBalancePadding<A, B, [0, ...C], []> : C['length'] extends A ? [R, 'A'] : C['length'] extends B ? [R, 'B'] : GetBalancePadding<A, B, [0, ...C], [0, ...R]>;
/**
* This is used to align the `NumberStruct` during `Add/Subtract`.
*/
export type GetMinPadEnd<A extends number, B extends number, R extends number[] = []> = R['length'] extends A ? [R, 'B'] : R['length'] extends B ? [R, 'A'] : GetMinPadEnd<A, B, [0, ...R]>;
export {};
}
export declare namespace DigitArray {
export type FromString<S extends string> = S extends `1${infer L}` ? [1, ...FromString<L>] : S extends `2${infer L}` ? [2, ...FromString<L>] : S extends `3${infer L}` ? [3, ...FromString<L>] : S extends `4${infer L}` ? [4, ...FromString<L>] : S extends `5${infer L}` ? [5, ...FromString<L>] : S extends `6${infer L}` ? [6, ...FromString<L>] : S extends `7${infer L}` ? [7, ...FromString<L>] : S extends `8${infer L}` ? [8, ...FromString<L>] : S extends `9${infer L}` ? [9, ...FromString<L>] : S extends `0${infer L}` ? [0, ...FromString<L>] : S extends `-1${infer L}` ? [-1, ...FromString<L>] : S extends `-2${infer L}` ? [-2, ...FromString<L>] : S extends `-3${infer L}` ? [-3, ...FromString<L>] : S extends `-4${infer L}` ? [-4, ...FromString<L>] : S extends `-5${infer L}` ? [-5, ...FromString<L>] : S extends `-6${infer L}` ? [-6, ...FromString<L>] : S extends `-7${infer L}` ? [-7, ...FromString<L>] : S extends `-8${infer L}` ? [-8, ...FromString<L>] : S extends `-9${infer L}` ? [-9, ...FromString<L>] : S extends `-0${infer L}` ? [-0, ...FromString<L>] : [];
export type ToString<A extends Array<number | string>> = number extends A['length'] ? '' : A['length'] extends 0 ? '' : `${A[0]}${ToString<Tail<A>>}`;
/**
* [0, 0, -1] => [-1]
*
* This is used in various places so that there will be less computation,
* and the sign bit can be handled properly.
*/
export type TrimLeadingZeros<T extends number[]> = T extends [0] ? T : T extends [0, ...infer Tail extends number[]] ? TrimLeadingZeros<Tail> : T;
export type TrimTrailingZeros<T extends number[]> = T extends [0] ? T : T extends [...infer Tail extends number[], 0] ? TrimTrailingZeros<Tail> : T;
export type Add<A extends number[], B extends number[], R extends number[] = []> = A extends [] ? B extends [] ? R : B extends [...infer BH extends number[], infer BL extends number] ? Add<[], BH, [BL, ...R]> : never : B extends [] ? A extends [...infer AH extends number[], infer AL extends number] ? Add<AH, [], [AL, ...R]> : never : [A, B] extends [
[
...infer AH extends number[],
infer AL extends number
],
[
...infer BH extends number[],
infer BL extends number
]
] ? Add<AH, BH, [Digit.Add<AL, BL>, ...R]> : never;
export type Subtract<A extends number[], B extends number[], R extends number[] = []> = A extends [] ? B extends [] ? TrimLeadingZeros<R> : B extends [...infer BH extends number[], infer BL extends number] ? Subtract<[], BH, [ToNegative<BL>, ...R]> : never : B extends [] ? A extends [...infer AH extends number[], infer AL extends number] ? Subtract<AH, [], [AL, ...R]> : never : [A, B] extends [
[
...infer AH extends number[],
infer AL extends number
],
[
...infer BH extends number[],
infer BL extends number
]
] ? Subtract<AH, BH, [Digit.Subtract<AL, BL>, ...R]> : never;
export type Multiply<A extends number[], B extends number[], R extends number[][] = []> = B extends [] ? RecursiveAdd<R> : B extends [infer Head extends number, ...infer Tail extends number[]] ? Multiply<A, Tail, [...R, CarryDigits<MultiplyArray<A, Head, Zeros<Tail['length']>>>]> : never;
type Zeros<N extends number, R extends number[] = []> = N extends unknown ? R['length'] extends N ? R : Zeros<N, [0, ...R]> : never;
type MultiplyArray<A extends number[], B extends number, Pad extends number[], R extends number[] = []> = B extends 0 ? [0] : B extends 1 ? [...A, ...Pad] : A extends [] ? [...R, ...Pad] : A extends [infer H extends number, ...infer T extends number[]] ? MultiplyArray<T, B, Pad, [...R, Digit.Multiply<H, B>]> : never;
/**
* Recursively add digit arrays.
*
* This is used in multiplication.
*/
type RecursiveAdd<E extends number[][], R extends number[] = []> = E extends [] ? R : E extends [infer H extends number[], ...infer T extends number[][]] ? RecursiveAdd<T, CarryDigits<Add<R, H>>> : never;
export type CarryDigits<N extends number[], R extends number[] = []> = N extends [] ? TrimLeadingZeros<R> : N extends [infer Tail extends number] ? `${Tail}` extends `${infer T1 extends number}${infer T2 extends number}` ? CarryDigits<[], [T1, T2, ...R]> : `${Tail}` extends `-${infer T1 extends number}${infer T2 extends number}` ? `-${T1}` extends `${infer NT extends number}` ? CarryDigits<[], [NT, T2, ...R]> : never : CarryDigits<[], [Tail, ...R]> : N extends [infer Head extends number, infer Tail extends number] ? `${Tail}` extends `${infer T1 extends number}${infer T2 extends number}` ? CarryDigits<[Digit.Add<Head, T1>], [T2, ...R]> : `${Tail}` extends `-${infer T1 extends number}${infer T2 extends number}` ? `-${T1}` extends `${infer NT extends number}` ? CarryDigits<[Digit.Add<Head, NT>], [T2, ...R]> : never : `${Tail}` extends `-${number}` ? CarryDigits<[Digit.Add<Head, -1>], [Digit.Plus10[Tail], ...R]> : CarryDigits<[Head], [Tail, ...R]> : N extends [...infer Heads extends number[], infer Head extends number, infer Tail extends number] ? `${Tail}` extends `${infer T1 extends number}${infer T2 extends number}` ? CarryDigits<[...Heads, Digit.Add<Head, T1>], [T2, ...R]> : `${Tail}` extends `-${infer T1 extends number}${infer T2 extends number}` ? `-${T1}` extends `${infer NT extends number}` ? CarryDigits<[...Heads, Digit.Add<Head, NT>], [T2, ...R]> : never : `${Tail}` extends `-${number}` ? CarryDigits<[...Heads, Digit.Add<Head, -1>], [Digit.Plus10[Tail], ...R]> : CarryDigits<[...Heads, Head], [Tail, ...R]> : never;
export {};
}
export declare namespace Digit {
/**
* Adds two `Digit`.
*
* add: A: 0 - 9, B: 0 - 9
* normalize: [81, 81] -> [81 + 8, 1]
*/
export type Add<A extends number, B extends number> = `${A}` extends `-${infer AD extends number}` ? `${B}` extends `-${infer BD extends number}` ? ToNegative<PositiveEntryAdd<AD, BD>> : Subtract<B, AD> : `${B}` extends `-${infer BD extends number}` ? Subtract<A, BD> : PositiveEntryAdd<A, B>;
export type FlipSign<T extends number> = T extends 0 ? 0 : `${T}` extends `-${infer R extends number}` ? R : `-${T}` extends `${infer R extends number}` ? R : never;
type PositiveEntryAdd<A extends number, B extends number> = [
[
0,
1,
2,
3,
4,
5,
6,
7,
8,
9
],
[
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
[
2,
3,
4,
5,
6,
7,
8,
9,
10,
11
],
[
3,
4,
5,
6,
7,
8,
9,
10,
11,
12
],
[
4,
5,
6,
7,
8,
9,
10,
11,
12,
13
],
[
5,
6,
7,
8,
9,
10,
11,
12,
13,
14
],
[
6,
7,
8,
9,
10,
11,
12,
13,
14,
15
],
[
7,
8,
9,
10,
11,
12,
13,
14,
15,
16
],
[
8,
9,
10,
11,
12,
13,
14,
15,
16,
17
],
[
9,
10,
11,
12,
13,
14,
15,
16,
17,
18
],
[
10,
11,
12,
13,
14,
15,
16,
17,
18,
19
],
[
11,
12,
13,
14,
15,
16,
17,
18,
19,
20
],
[
12,
13,
14,
15,
16,
17,
18,
19,
20,
21
],
[
13,
14,
15,
16,
17,
18,
19,
20,
21,
22
],
[
14,
15,
16,
17,
18,
19,
20,
21,
22,
23
],
[
15,
16,
17,
18,
19,
20,
21,
22,
23,
24
],
[
16,
17,
18,
19,
20,
21,
22,
23,
24,
25
],
[
17,
18,
19,
20,
21,
22,
23,
24,
25,
26
],
[
18,
19,
20,
21,
22,
23,
24,
25,
26,
27
],
[
19,
20,
21,
22,
23,
24,
25,
26,
27,
28
],
[
20,
21,
22,
23,
24,
25,
26,
27,
28,
29
],
[
21,
22,
23,
24,
25,
26,
27,
28,
29,
30
],
[
22,
23,
24,
25,
26,
27,
28,
29,
30,
31
],
[
23,
24,
25,
26,
27,
28,
29,
30,
31,
32
],
[
24,
25,
26,
27,
28,
29,
30,
31,
32,
33
],
[
25,
26,
27,
28,
29,
30,
31,
32,
33,
34
],
[
26,
27,
28,
29,
30,
31,
32,
33,
34,
35
],
[
27,
28,
29,
30,
31,
32,
33,
34,
35,
36
],
[
28,
29,
30,
31,
32,
33,
34,
35,
36,
37
],
[
29,
30,
31,
32,
33,
34,
35,
36,
37,
38
],
[
30,
31,
32,
33,
34,
35,
36,
37,
38,
39
],
[
31,
32,
33,
34,
35,
36,
37,
38,
39,
40
],
[
32,
33,
34,
35,
36,
37,
38,
39,
40,
41
],
[
33,
34,
35,
36,
37,
38,
39,
40,
41,
42
],
[
34,
35,
36,
37,
38,
39,
40,
41,
42,
43
],
[
35,
36,
37,
38,
39,
40,
41,
42,
43,
44
],
[
36,
37,
38,
39,
40,
41,
42,
43,
44,
45
],
[
37,
38,
39,
40,
41,
42,
43,
44,
45,
46
],
[
38,
39,
40,
41,
42,
43,
44,
45,
46,
47
],
[
39,
40,
41,
42,
43,
44,
45,
46,
47,
48
],
[
40,
41,
42,
43,
44,
45,
46,
47,
48,
49
],
[
41,
42,
43,
44,
45,
46,
47,
48,
49,
50
],
[
42,
43,
44,
45,
46,
47,
48,
49,
50,
51
],
[
43,
44,
45,
46,
47,
48,
49,
50,
51,
52
],
[
44,
45,
46,
47,
48,
49,
50,
51,
52,
53
],
[
45,
46,
47,
48,
49,
50,
51,
52,
53,
54
],
[
46,
47,
48,
49,
50,
51,
52,
53,
54,
55
],
[
47,
48,
49,
50,
51,
52,
53,
54,
55,
56
],
[
48,
49,
50,
51,
52,
53,
54,
55,
56,
57
],
[
49,
50,
51,
52,
53,
54,
55,
56,
57,
58
],
[
50,
51,
52,
53,
54,
55,
56,
57,
58,
59
],
[
51,
52,
53,
54,
55,
56,
57,
58,
59,
60
],
[
52,
53,
54,
55,
56,
57,
58,
59,
60,
61
],
[
53,
54,
55,
56,
57,
58,
59,
60,
61,
62
],
[
54,
55,
56,
57,
58,
59,
60,
61,
62,
63
],
[
55,
56,
57,
58,
59,
60,
61,
62,
63,
64
],
[
56,
57,
58,
59,
60,
61,
62,
63,
64,
65
],
[
57,
58,
59,
60,
61,
62,
63,
64,
65,
66
],
[
58,
59,
60,
61,
62,
63,
64,
65,
66,
67
],
[
59,
60,
61,
62,
63,
64,
65,
66,
67,
68
],
[
60,
61,
62,
63,
64,
65,
66,
67,
68,
69
],
[
61,
62,
63,
64,
65,
66,
67,
68,
69,
70
],
[
62,
63,
64,
65,
66,
67,
68,
69,
70,
71
],
[
63,
64,
65,
66,
67,
68,
69,
70,
71,
72
],
[
64,
65,
66,
67,
68,
69,
70,
71,
72,
73
],
[
65,
66,
67,
68,
69,
70,
71,
72,
73,
74
],
[
66,
67,
68,
69,
70,
71,
72,
73,
74,
75
],
[
67,
68,
69,
70,
71,
72,
73,
74,
75,
76
],
[
68,
69,
70,
71,
72,
73,
74,
75,
76,
77
],
[
69,
70,
71,
72,
73,
74,
75,
76,
77,
78
],
[
70,
71,
72,
73,
74,
75,
76,
77,
78,
79
],
[
71,
72,
73,
74,
75,
76,
77,
78,
79,
80
],
[
72,
73,
74,
75,
76,
77,
78,
79,
80,
81
],
[
73,
74,
75,
76,
77,
78,
79,
80,
81,
82
],
[
74,
75,
76,
77,
78,
79,
80,
81,
82,
83
],
[
75,
76,
77,
78,
79,
80,
81,
82,
83,
84
],
[
76,
77,
78,
79,
80,
81,
82,
83,
84,
85
],
[
77,
78,
79,
80,
81,
82,
83,
84,
85,
86
],
[
78,
79,
80,
81,
82,
83,
84,
85,
86,
87
],
[
79,
80,
81,
82,
83,
84,
85,
86,
87,
88
],
[
80,
81,
82,
83,
84,
85,
86,
87,
88,
89
],
[
81,
82,
83,
84,
85,
86,
87,
88,
89,
90
]
][A][B];
/**
* Subtract two positive numbers.
* The number range from 0 to 81.
*/
export type Subtract<A extends number, B extends number> = [`${A}`, `${B}`] extends [
`${number}${infer A2 extends number}`,
`${number}${infer B2 extends number}`
] ? Subtract<A2, B2> : `${A}` extends `${number}${infer A2 extends number}` ? Subtract<A2, B> : `${B}` extends `${number}${infer B2 extends number}` ? Subtract<A, B2> : SingleDigitSubtract<A, B>;
export type SingleDigitSubtract<A extends number, B extends number> = [
[
0,
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-8,
-9
],
[
1,
0,
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-8
],
[
2,
1,
0,
-1,
-2,
-3,
-4,
-5,
-6,
-7
],
[
3,
2,
1,
0,
-1,
-2,
-3,
-4,
-5,
-6
],
[
4,
3,
2,
1,
0,
-1,
-2,
-3,
-4,
-5
],
[
5,
4,
3,
2,
1,
0,
-1,
-2,
-3,
-4
],
[
6,
5,
4,
3,
2,
1,
0,
-1,
-2,
-3
],
[
7,
6,
5,
4,
3,
2,
1,
0,
-1,
-2
],
[
8,
7,
6,
5,
4,
3,
2,
1,
0,
-1
],
[
9,
8,
7,
6,
5,
4,
3,
2,
1,
0
]
][A][B];
export type Plus10 = {
[k in number]: number;
} & {
'-1': 9;
'-2': 8;
'-3': 7;
'-4': 6;
'-5': 5;
'-6': 4;
'-7': 3;
'-8': 2;
'-9': 1;
};
export type Multiply<A extends number, B extends number> = [
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
[
0,
1,
2,
3,
4,
5,
6,
7,
8,
9
],
[
0,
2,
4,
6,
8,
10,
12,
14,
16,
18
],
[
0,
3,
6,
9,
12,
15,
18,
21,
24,
27
],
[
0,
4,
8,
12,
16,
20,
24,
28,
32,
36
],
[
0,
5,
10,
15,
20,
25,
30,
35,
40,
45
],
[
0,
6,
12,
18,
24,
30,
36,
42,
48,
54
],
[
0,
7,
14,
21,
28,
35,
42,
49,
56,
63
],
[
0,
8,
16,
24,
32,
40,
48,
56,
64,
72
],
[
0,
9,
18,
27,
36,
45,
54,
63,
72,
81
]
][A][B];
export {};
}
export {};
//# sourceMappingURL=numeric_struct.d.ts.map