Skip to content

Instantly share code, notes, and snippets.

@zachhardesty7
Last active February 4, 2022 00:04
Show Gist options
  • Save zachhardesty7/4b88be5dbc4ce1d00c37df0d1811c48b to your computer and use it in GitHub Desktop.
Save zachhardesty7/4b88be5dbc4ce1d00c37df0d1811c48b to your computer and use it in GitHub Desktop.
TypeScript Types binary to decimal exploration
// copyright 2022 Zach Hardesty
// want to check this out in the TypeScript playground?
// visit the following link to automatically see the latest version!
// https://www.typescriptlang.org/play?jsx=0#gist/4b88be5dbc4ce1d00c37df0d1811c48b
// experiments that have thus far been unsuccessful
// https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
// https://github.com/fightingcat/sits
// https://github.com/kddnewton/typescript-parse-math
// https://github.com/ronami/meta-typing
// https://github.com/ghoullier/awesome-template-literal-types#bitwise-arithmetic
// https://www.typescriptlang.org/play?ts=4.5.0-dev.20210908#code/C4TwDgpgBAsgggDQJIwKowPpwDLYPIDqAogCIYBCeqAciXAEoCaUAvFACwCcArALABQA0JFgBDMJAAmAHgFR5UalAgAPYBAB2kgM5QNAVwC2AIwgAnADRyF9CNv0AbYMrWadUOGbOiQ0-RoBrDQB7AHcNAD5WKABtAF0rfgUoKJZreQAKW3snGIByB00Ac2AACzy4l3UtXWp05KgAfihsx2B65IAuMQkIGWoLWIA6EdanQbHgfMKNEvK4uIj6gEoBAQB6dagABihBgEZBgCYoEaGOTnYhcGhqI1MzelFZ6DYYcSlpeGQ0TBx8YhkSg0OhMCIxAwmcxxNaCfjCaAAFVUwG00kRVTcugACmZgpAzKAANIQECpKAYlFYvT3cxNKAAA3UagAJABvREAXwZUG6GggADdzLDriIMWwDA4HFAAD5QABEon0wGC8tlFJRaLuUMezyKEAiAG5YQioCQAJYAY2A5uCGlEZhA0TZ9RiuPxUHNGkUtN1Lygol0DPZ7rA3Li3VDAk5sM28l2cv26pOcoAzOr2OruOqAGzqgDs6oAHOrOOr9rszhcrvCbopWPUiGpvNb0YMmSj2ZCHtyolSaozmcB2V6AGZ0+jc+rNeiYgcBUnBUdmq02u0OkDTlfW232x0xegwpIKPmC4XH+SnoVmEX8IA
// https://www.typescriptlang.org/play?ts=4.5.0-dev.20211012#code/C4TwDgpgBAsgggDQJIwKowPpwDLYPIDqAogCIYBCeqAciXAEoCaUAvFAJycCwAUL6JFgBDMJAAmAHl5QZUalAgAPYBAB2YgM5RVAVwC2AIwgAnADTTZ9CBp0AbYAuVrNUOMeNCQEnaoDWqgHsAd1UAPlYoAG0AXXMeWShwlgsZAAorG3tIgHJbNQBzYAALbOjHFXUtahSEqAB+KAy7YBqEgC5hUQhJalMogDpBpvs+4eAcvNVCkujo0JqASl5lngFoan0jY3ohKeg2GBFxCXhkNEwcfGIySho6JlDI3UMTaJX+cGgAYQDVADcTMAACoBDYvYwSIHlZxaDTAYwASymo12+WgSgqLmeWySNXSqPRTkqUF2IFasgaqQABgASADeOz2AF8qdDiUDybV6o0CZzah1VBAAcYlvEuVABUKTKKPoIMBEfv9ASCwVsJNkAKzZPqqkyMtHhAD0hqgGtl0Aw8rYiuFwNBmxM6oAjAAmLU6h3bAlGk2us18HhAA
// https://www.typescriptlang.org/play?ts=4.5.0-dev.20211012&ssl=9&ssc=25&pln=9&pc=31#code/C4TwDgpgBAsgggDQJIwKowPpwDLYPIDqAogCIYBCeqAciXAEoCaUAvFAJycCwAUL6JFgBDMJAAmAHl5QZUalAgAPYBAB2YgM5RVAVwC2AIwgAnADTTZ9CBp0AbYAuVrNUOMeNCQEnaoDWqgHsAd1UAPlYoAG0AXXMeWShwlgsZAAorG3tIgHJbNQBzYAALbOjHFXUtahSEqAB+KAy7YBqEgC5hUQhJalMogDpBpvs+4eAcvNVCkujo0JqASl5lngFoan0jY3ohKeg2GBFxCXhkNEwcfGIySho6JlCAbhX+cGgAYQDVADcTYAAVAIbQwmCT-crOLQaYDGACWU1Gu3y0CUFRcuhBxhiSQs4NRkKgvggIACADNGkjoA0dntIv8yh1VBBfsZnnxVm8oBgIp8fn9AcCthJsgBWbJ9QUmGnI8IAellUBFr0EGG5bF5LIBQM2oOyAEYAExiiU67aUuUKw1K9lAA
type decimalMapA = {
"0000": "0"
"0001": "1"
"0010": "2"
"0011": "3"
"0100": "4"
"0101": "5"
"0110": "6"
"0111": "7"
"1000": "8"
"1001": "9"
}
/** numbers with a carried digit in base 10 */
type decimalMapB = {
"1010": "0"
"1011": "1"
"1100": "2"
"1101": "3"
"1110": "4"
"1111": "5"
}
type decimalMapInc = {
"0": "1"
"1": "2"
"2": "3"
"3": "4"
"4": "5"
"5": "6"
"6": "7"
"7": "8"
"8": "9"
"9": "0"
}
type IncDecCarry<Dec extends string> = Dec extends keyof decimalMapInc
? Dec extends "9"
? [decimalMapInc[Dec], One]
: [decimalMapInc[Dec], Zero]
: never
/** note, must be multiple of 4, well exactly 4 bc this algorithm isn't how math works... */
type binToDecString<
Bin extends string,
Out extends string = "",
Carry extends string = Zero,
> = Bin extends ""
? Carry extends One
? `1${Out}`
: Out
: Bin extends `${infer Rest}${Nibble}`
? Bin extends `${Rest}${infer D}`
? D extends keyof decimalMapA
? Carry extends One
? binToDecString<
Rest,
`${IncDecCarry<decimalMapA[D]>[0]}${Out}`,
IncDecCarry<decimalMapA[D]>[1]
>
: binToDecString<Rest, `${decimalMapA[D]}${Out}`, Zero>
: D extends keyof decimalMapB
? binToDecString<Rest, `${decimalMapB[D]}${Out}`, One>
: never
: never
: never
type TEST_DEC_00 = Expect<binToDecString<"0111">, "7">
type TEST_DEC_01 = Expect<binToDecString<"0000">, "0">
type TEST_DEC_02 = Expect<binToDecString<"1010">, "10">
type TEST_DEC_03 = Expect<binToDecString<"1111">, "15">
// type TEST_DEC_04 = Expect<binToDecString<"00101010">, "42">
// subtract 9 in a loop?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment