Skip to content

Using TypeScript's Type System to do 8-bit Arithmetic

License

Notifications You must be signed in to change notification settings

sinclairzx81/ts-8-bit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TS-8-bit

Using TypeScript's Type System to do 8-bit Arithmetic

import { 
    Byte, Num, Add, Sub, Mul, Div, Mod, Eq, Lt, Gt, Lte, Gte, Lsh, Rsh, And, Xor, Or, Not 
} from './ts-8-bit'

// Arithmetic
type A = Num< Add < Byte<12>, Byte<22> > >  // + type A = 34
type B = Num< Sub < Byte<47>, Byte<12> > >  // - type B = 35
type C = Num< Mul < Byte<31>, Byte<4>  > >  // * type C = 124
type D = Num< Div < Byte<16>, Byte<8>  > >  // / type D = 2
type E = Num< Mod < Byte<19>, Byte<4>  > >  // % type E = 3

// Equality
type F = Eq < Byte<10>, Byte<10> >          // == type F = true
type G = Lt < Byte<10>, Byte<10> >          // <  type G = false
type H = Gt < Byte<20>, Byte<10> >          // >  type H = true
type I = Lte< Byte<10>, Byte<10> >          // <= type I = true
type J = Gte< Byte<20>, Byte<10> >          // >= type J = true

// Bitwise
type K = Num< Rsh < Byte<64>, 3 > >         // >> type K = 8
type L = Num< Lsh < Byte<23>, 2 > >         // << type L = 92
type M = Num< Or  < Byte<33>, Byte<7> > >   // |  type M = 39 
type N = Num< And < Byte<12>, Byte<5> > >   // &  type N = 4
type O = Num< Xor < Byte<22>, Byte<17 > > > // ^  type O = 7
type P = Num< Not < Byte<253> > >           // !  type P = 2

Overview

ts-8-bit is an experimental library that does 8-bit arithmetic on TypeScript's type system. It does so by applying bitwise operations on tuples of length 8 (1 byte) and leverages TypeScript conditional type inference to give the result. This project was written as a exercise in TypeScript and is offered as is for anyone who may find it of use.

Requires TypeScript 4.1.2 and above. Example link here.

License MIT

Usage

The following demonstrates basic usage.

import { Byte, Num, Add, Sub, Mod } from './ts-8-bit'

// ------------------------------------------------------------------------
//
// Use Byte<T> and Num<T> to map between bytes and numbers
//
// ------------------------------------------------------------------------

type A = Byte<127>                           // type A = [1, 1, 1, 1, 1, 1, 1, 0]

type B = Num<[1, 1, 1, 1, 1, 1, 1, 0]>       // type B = 127

type C = Num< Byte<55> >                     // type C = 55

// ------------------------------------------------------------------------
//
// ... with math done exclusively on bytes ...
//
// ------------------------------------------------------------------------

type D = Add<                                // type D = [0, 1, 1, 1, 1, 1, 1, 1]
    [1, 1, 1, 1, 1, 1, 1, 0], 
    [1, 1, 1, 1, 1, 1, 1, 0]
>

// ------------------------------------------------------------------------
//
// ... but can be remapped this way ...
//
// ------------------------------------------------------------------------

type E = Num< Add< Byte<127>, Byte<127> > >  // type E = 254

// ------------------------------------------------------------------------
//
// ... and used for stuff like ...
//
// ------------------------------------------------------------------------

type FizzBuzz<T extends Byte<any>> = 
     Mod<T, Byte<5>> extends Byte<0> ? 
     Mod<T, Byte<3>> extends Byte<0> ? 'fizzbuzz' : 'buzz' :
     Mod<T, Byte<3>> extends Byte<0> ? 'fizz'     : ""

type T1  = FizzBuzz< Byte<1> >     // ""
type T2  = FizzBuzz< Byte<2> >     // ""
type T3  = FizzBuzz< Byte<3> >     // "fizz"
type T4  = FizzBuzz< Byte<4> >     // ""
type T5  = FizzBuzz< Byte<5> >     // "buzz"
type T6  = FizzBuzz< Byte<6> >     // "fizz"
// ... etc ...
type T15 = FizzBuzz< Byte<15> >    // "fizzbuzz"

// ------------------------------------------------------------------------
//
// ... or something more elaborate ...
//
// ------------------------------------------------------------------------

type IsPrimeOp<
    A extends [Bit, Bit, Bit, Bit, Bit, Bit, Bit, Bit],
    B extends [Bit, Bit, Bit, Bit, Bit, Bit, Bit, Bit]
> = Num<B>         extends 1 ? true  : 
    Num<Mod<A, B>> extends 0 ? false : 
    IsPrimeOp<A, Sub<B, Byte<1>>>

type IsPrime<
    A extends [Bit, Bit, Bit, Bit, Bit, Bit, Bit, Bit]
> = IsPrimeOp<A, Sub<A, Byte<1>>>

type P3  = IsPrime< Byte<3> >      // true
type P4  = IsPrime< Byte<4> >      // false
type P5  = IsPrime< Byte<5> >      // true
type P6  = IsPrime< Byte<6> >      // false
type P7  = IsPrime< Byte<7> >      // true
type P8  = IsPrime< Byte<8> >      // false
type P9  = IsPrime< Byte<9> >      // false
type P10 = IsPrime< Byte<10> >     // false
type P11 = IsPrime< Byte<11> >     // true
type P12 = IsPrime< Byte<12> >     // false
type P13 = IsPrime< Byte<13> >     // true
type P14 = IsPrime< Byte<14> >     // false
type P15 = IsPrime< Byte<15> >     // false
type P16 = IsPrime< Byte<16> >     // false
type P17 = IsPrime< Byte<17> >     // true - pushing recursion limits here
type P18 = IsPrime< Byte<18> >     // false

About

Using TypeScript's Type System to do 8-bit Arithmetic

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published