import { Digit, Digits, TrimZeros } from "../utils"; import { CompareDigits } from "../compare"; import { AddDigits } from "./addition"; import { SubDigits } from "./substraction"; export type Rest = T extends [ Digit, ...infer R extends Digit[] ] ? R : never; type TruncateWith = U extends [] ? [T, Acc] : T extends [infer D extends Digit, ...infer DR extends Digit[]] ? TruncateWith, [...Acc, D]> : [T, Acc]; type DivModByDigit, Comp = CompareDigits> = IterTable extends [ infer Iteration extends Digit, ...infer Next extends Digit[] ] ? Comp extends 0 ? { Quotient: Next[0]; Remainder: [0]; } : Comp extends 1 ? DivModByDigit : { Quotient: Iteration; Remainder: SubDigits; } : never; /** * compute the long division of a number by a divisor * @param A the Numerator Cut after M digits * @param D the Numerator Cut with M first digits * @param M the Divisor * @param Q the Quotient * @see https://en.wikipedia.org/wiki/Long_division#Algorithm_for_arbitrary_base */ export type _DivModDigits = DivModByDigit extends { Quotient: infer B extends Digit; Remainder: infer R extends Digit[]; } ? A extends [infer A1 extends Digit, ...infer AR extends Digit[]] ? _DivModDigits, M, [...Q, B]> : { Quotient: [...Q, B]; Remainder: R; } : never; export type DivDigits = TruncateWith extends [infer A extends Digit[], infer D extends Digit[]] ? _DivModDigits["Quotient"] : never; export type ModDigits = TruncateWith extends [infer A extends Digit[], infer D extends Digit[]] ? _DivModDigits["Remainder"] : never; export type DivModDigits = TruncateWith extends [infer A extends Digit[], infer D extends Digit[]] ? _DivModDigits : never; export {};