|
前置:使用typescript类型系统实现正整数加法运算 https://klpbbs.com/thread-145895-1-1.html 一下使用的部分工具类型定义在此 声明:没有用的东西,没事不要学 由于typescript不能使用+-*/,所以我们需要自定义乘法表 type multiplication_table_key = [ '00','01','02','03','04','05','06','07','08','09','11','12','13','14','15','16','17','18','19','22','23','24','25','26','27','28','29','33','34','35','36','37','38','39','44','45','46','47','48','49','55','56','57','58','59','66','67','68','69','77','78','79','88','89','99' ] type multiplication_table_value = [ ...fill_array<[],10,'0'>,'1','2','3','4','5','6','7','8','9','4','6','8','10','12','14','16','18','9','12','15','18','21','24','27','16','20','24','28','32','36','25','30','35','40','45','36','42','48','54','49','56','63','64','72','81' ] 要计算乘法,不可避免的要进行进位,由于每次进位不再像加法那样最多为1,所以我们需要一个工具类型获取进位:实现 type string_remove_end<s extends string,target extends ''> = isOne<s,get_string_top<s>> extends true ? target : string_remove_end<string_remove_top<s>,`${target}${get_string_top<s>}`> 接着,模仿人类手算,我们要先学会个位乘个位,利用上面的列表,填入两个字符串进行匹配,实现 type multiplication<x extends string,y extends string,index = 0> = multiplication_table_key[index] extends undefined ? undefined : true extends isOne<`${x}${y}`,multiplication_table_key[index]> ? multiplication_table_value[index] : true extends isOne<`${y}${x}`,multiplication_table_key[index]> ? multiplication_table_value[index] : multiplication<x,y,ad<index,1>> 学会了这个,就可以进行个位乘N位的运算了,我们先不处理进位,把每一位相乘的结果存在元组里,实现 type multiplication_x<x extends string,y extends string[],storage extends []> = true extends isOne<y,[]> ? storage : multiplication_x<x,array_remove_end<y>,[multiplication<x,get_array_end<y>>,...storage]> 然后,根据这个元组,我们对其进行进位处理,实现 type multiplication_carry<current extends string[],handle extends []> = true extends isOne<current,[]> ? handle : true extends isOne<current['length'],1> ? [...StringToArray<current[0]>,...handle] : multiplication_carry<[...array_remove_end<array_remove_end<current>>,add<get_array_end<array_remove_end<current>>,string_remove_end<get_array_end<current>,''>>],[string_get_end<get_array_end<current>>,...handle]> 他会把['1','12']转化成['2','2'] 之后就可以进行多位乘多位的运算了,不过在此之前,我们需要先获取那个位数比较短的,回忆自己列式计算的时候,是不是这样,实现 type min_length_array<x extends any[],y extends any[],storage extends []> = true extends isOne<x[storage['length']],undefined> ? x : true extends isOne<y[storage['length']],undefined> ? y : min_length_array<x,y,[0,...storage]> 之后我们遍历短的元组,让他去乘长的元组的所有位,并储存起来,还有,当第二位开始乘时,结果就要补0了,我们模仿的是这个运算 23*123 0369 2460 实现 type multiplications<x extends string[],y extends string[],storage extends []> = true extends isOne<x,[]> ? storage : true extends isOne<y,[]> ? storage : true extends isOne<x,min_length_array<x,y,[]>> ? multiplications<array_remove_end<x>,y,[...storage,[...multiplication_carry<multiplication_x<get_array_end<x>,y,[]>,[]>,...fill_array<[],storage['length'],'0'>]]> : multiplications<array_remove_end<y>,x,[...storage,[...multiplication_carry<multiplication_x<get_array_end<y>,x,[]>,[]>,...fill_array<[],storage['length'],'0'>]]> 最后,我们把他相加,可得最终结果 type multiplication__<a extends string[][],result extends '0'> = true extends isOne<a,[]> ? result : multiplication__<array_remove_end<a>,add<array_to_string<get_array_end<a>,''>,result>> 然后再把元组转化成人能看懂的字符串,一个计算乘法的工具类型就写好了,实现 export type Multiplication<x extends string,y extends string> = multiplication__<multiplications<StringToArray<x>,StringToArray<y>,[]>,'0'> 乘法运算在有了乘法后很简单,不断调用该工具类型就好,实现 type multiplying_power<x extends string,y extends string,times extends string,result extends '1'> = true extends isOne<y,times> ? result : multiplying_power<x,y,add<times,'1'>,Multiplication<result,x>> type MultiplicationPower<x extends string,y extends string> = multiplying_power<x,y,'1','1'> 效果
|
提升卡
观察者