开启辅助访问     
收藏本站

站内搜索

搜索

Minecraft(我的世界)苦力怕论坛

[其他] 使用typescript类型体操实现正整数乘法和乘方运算

 发表于 2024-8-26 13:58:13 来自手机|显示全部楼层|阅读模式 IP:安徽省
前置:使用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'>
效果
Screenshot_2024-08-26-02-32-31-19_f9a7afa717ced9e1fc9be9833291031a.jpg
苦力怕论坛,感谢有您~

本版积分规则

本站
关于我们
联系我们
坛史纲要
官方
哔哩哔哩
技术博客
下载
网易版
安卓版
JAVA
反馈
意见建议
教程中心
更多
捐助本站
QQ群
QQ群

QQ群

访问手机版

访问手机版

手机版|小黑屋|系统状态|klpbbs.com

粤公网安备 44200002445329号 | 由 木韩网络 提供云服务 | GMT+8, 2024-9-27 07:18

声明:本站与Mojang以及微软公司没有从属关系

Powered by Discuz! X3.4 粤ICP备2023071842号