import { And } from "../../boolean"; import { AsNumber, Reverse } from "../../string"; import { Unreachable } from "../../type"; import { StripLeadingZeros } from "../string"; import { Negate } from ".."; import { _PadZeros } from "./_pad-zeros"; import { ValidateNonnegInt, ValidateInt } from "./_validate"; import { _AddNonneg, _DecPos } from "."; /** * list mapping digits to the resultant digit for subtraction. used to compute `D1 - D2` when `D2 > D1`: * the resultant digit is `TenMinus[D2 - D1]` */ type TenMinus = [never, 9, 8, 7, 6, 5, 4, 3, 2, 1]; type _Max = D1 extends 0 ? O2 : D2 extends 0 ? O1 : _Max<_DecPos, _DecPos, O1, O2>; /** * finds the greater of digits `D1` and `D2` * since it assumes inputs are single digits, does not necessarily work on larger numbers due to recursion limit */ type Max = D1 extends D2 ? D1 : _Max; type BorrowDigit = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8]; type SubtractionTable = [ [ 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 ] ]; declare const __NEGATIVE__: unique symbol; type __NEGATIVE__ = typeof __NEGATIVE__; /** * subtracts integer `N2` from integer `N1`, represented in their reverse serialized forms `S1` and `S2` */ type __Sub = S1 extends `${infer D1 extends number}${infer T1}` ? S2 extends `${infer D2 extends number}${infer T2}` ? (Borrow extends true ? BorrowDigit[D1] : D1) extends (infer D extends number) ? D extends Max ? __Sub, `${Acc}${SubtractionTable[D][D2]}`> : __Sub : Unreachable : Unreachable : Borrow extends true ? __NEGATIVE__ : Acc; /** * subtracts nonnegative integer `N2` from nonnegative integer `N1` * * @warning you probably want to use `SubNonneg` instead. this type does not enforce type constraints past `number`. * * @since 0.0.2 */ export type _SubNonneg = _PadZeros extends [`${infer S1}`, `${infer S2}`] ? __Sub, Reverse> extends infer X ? X extends string ? AsNumber>> : Negate<_SubNonneg> : Unreachable : Unreachable; /** * subtracts integer `N2` from integer `N1` * * @warning you probably want to use `Sub` instead. this type does not enforce type constraints past `number`. * * @since 0.0.2 */ export type _Sub = `${N1}` extends `-${infer Abs1 extends number}` ? `${N2}` extends `-${infer Abs2 extends number}` ? _SubNonneg : Negate<_AddNonneg> : `${N2}` extends `-${infer Abs2 extends number}` ? _AddNonneg : _SubNonneg; /** * subtracts nonnegative integer `N2` from nonnegative integer `N1` * * validates that `N1 and `N2` are in fact nonnegative integers * * @since 0.0.2 */ export type SubNonneg_Safe, N2 extends ValidateNonnegInt> = [ ValidateNonnegInt, ValidateNonnegInt ] extends [number, number] ? [N1, N2] extends [infer N1 extends number, infer N2 extends number] ? _SubNonneg : Unreachable : never; /** * subtracts integer `N2` from integer `N1` * * validates that `N1 and `N2` are in fact integers * * @since 0.0.2 */ export type Sub_Safe, N2 extends ValidateInt> = [ ValidateInt, ValidateInt ] extends [number, number] ? [N1, N2] extends [infer N1 extends number, infer N2 extends number] ? _Sub : Unreachable : never; export {}; //# sourceMappingURL=sub.d.ts.map