注册 登录
编程论坛 汇编论坛

大数相乘实现算法的相关想法 有容老兄要来哟!!!!敢给着个色么

zhu224039 发布于 2012-10-03 13:18, 1809 次点击

采用分治算法实现  包括两部分的分解
乘数和被乘数 的分解
设 乘数a是由数字集合a={a1,a2,a3...........an}   n代表的是a数的位数大于0的正整数 用 a=f(1,n)
设被乘数b是由数字集合b={b1,b2,b3..........bx}   x代表的是b数的位数大于0的正整数    b=f(1,x)

被乘数的分解算法
第一次分解 :
分解结果为:
lift={b1.........bx/2}
right={b(x/2+1).......bx}
用函数表达式   lift=F(1,b/2) ,right=F(x/2+1,x) 表示  n
那么 被乘数  a=lift*10^(x-x/2-1)+right
由乘法规则  (a+b)*c=a*c+b*c的 可以得到
a*b=a* lift*10^(x-x/2-1)+b*right 的表达式    的合并过程
下面怎么推算我就不推了  直接给通项表达式 设b=f(x,y)  则有 right=f(x,(x+y)/2)  lift=f((x+y)/2+1,y)
f(x,y)=(lift*10^(y-(x+y)/2-1)+right)*a  合并算法
存在
c 程序的代码段就为
乘数
fenjie(int num,int x, int y)
{
int q
q=(x+y)/2
while(q<y)
{
f1=fenjie (int num,int x,int (x+y)/2)
f2=fenjie(int num,int (x+y)/2+1,int y)
}
合并代码位置
代码完成功能     f(x,y)=(lift*10^(y-(x+y)/2-1)+right)*a  的计算
 这个是被乘数  
还得对a*bx进行求解  bx代表的是单个位数  再对a进行分解 变成 a的单个数位置上的与bx相乘 的分解合并求解过程,这个过程和上面的 代码是差不多的 嘿嘿
}
呵呵 算法描述完毕


[ 本帖最后由 zhu224039 于 2012-10-3 13:56 编辑 ]
26 回复
#2
zhu2240392012-10-03 13:26
算法出来了,
吧问题转换成了 大数加法的问题  嘿嘿   你懂得

将大数 如何 存放在不同的 16位 存储空间中  嘿嘿

这个也是个分解过程  将 大数 分解成 a=FFFFH+FFFFH+FFFFH+FFFFH+FFFFH+FFFFFH+X
的形式
上面的算法可以实现 区块与区块的运算   嘿嘿
将大数区块化
 区块的运算求解 又要分 两个数区块分解 做乘法运算的问题
区块分解的 (FFFFH+FFFFH+FFFFH+FFFFH+FFFFH+FFFFFH+X)*a
在对a 进行区块分解求解
又是一个 分治 合并的过程
嘿嘿  你敢写这个代码么


[ 本帖最后由 zhu224039 于 2012-10-3 13:37 编辑 ]
#3
zhu2240392012-10-03 13:40
我想代码其实不是很长哟,我只想用C语言编个 数组a 存放乘数 数组b 存放 被乘数的  两个数组的乘法算法拉倒


[ 本帖最后由 zhu224039 于 2012-10-3 13:47 编辑 ]
#4
zhu2240392012-10-03 14:04
另一种实现
汇编语言 还可以用压缩的数据类型 里面存放123456789  来存放 输入进去的数字字符
来模拟 十进制   乘法
数相乘的结果 BCD1*BCD *10^x的形式进行转换 存储到一个能放下这么大的一个数的 内存空间中去


这个实现过程要简单的多
#5
zhu2240392012-10-03 14:05
同样要用到上面的分治算法  实现   嘿嘿  在对算法进行下改进,不觉得麻烦的话就建立一个  9*9的 乘法表,加快程序处理速度 就更完美了

[ 本帖最后由 zhu224039 于 2012-10-3 14:09 编辑 ]
#6
zhu2240392012-10-03 14:37
  我想我弄明白了
#7
zhu2240392012-10-03 15:06
在进一步的朝前想,可以利用压缩型的十进制  0 1 2 3 4 5 6 7 8 9
他们的2位BCD数字 利用程序可以自动生成一个表 里面存放的是9*9正的10进制的16位二进制表
BCD码为4位1个数  那么就可以建立一张 映射表出
8位 二进制  ----------》10进制的 两BCD的二进制表的 映射关系
高4位 低4位  利用指令AND来屏蔽 4位 来表示BCD  4位表示BCD1   利用 移位指令来 生成这个 8位二进制

一个字有16位 用了低8位 ,高八位用来索引?
那么他的表示范围 就是0-9999  区间的 二进制表

对于一个16位数来说 这个是不够的  

模仿80386的内存的段管理模式  用 段选择符 :偏移地址的方式来做
建立一个段操作符----->二进制表-----》真正的二进制 过程来扩展

或者   8086的 基础地址+偏移地址 形成 物理过程的寻址 这个过程
几位呢
拿来当段操作符呢
我觉得映射 比较合理  

后面的在构思中 嘿嘿 吃饭去了
#8
有容就大2012-10-03 15:08
要能搞个代码出来 给你申请精华
#9
zhu2240392012-10-03 15:12
想好了怎么搞,才能更好的搞

具体搞什么 后面是联想
这里的搞=写代码
#10
zhu2240392012-10-03 15:14
好的    等我搞
#11
zklhp2012-10-03 15:34
高亮直接永久就好了 不用限时 帖子最终会沉下去 所以高亮了也看不见 和取消高亮一个效果。。

不知道这里的算法时间复杂度是啥。。 O(n^2) 么
#12
有容就大2012-10-03 15:39
汇编版的大数乘法(16位寄存器) 网上的资料很少,确实考验人。
不过我提醒下 这个大数至少也能写到个百把位,你用寄存器来存放大数的值,路子可能歪了。
那么几个可怜的寄存器是无法达到这个要求的。。。


#13
有容就大2012-10-03 15:40
以下是引用zklhp在2012-10-3 15:34:20的发言:

高亮直接永久就好了 不用限时 帖子最终会沉下去 所以高亮了也看不见 和取消高亮一个效果。。

不知道这里的算法时间复杂度是啥。。 O(n^2) 么

。。。。。。Z版,俺是第一次高亮给色 谢谢提点。
#14
zklhp2012-10-03 15:50
以下是引用有容就大在2012-10-3 15:40:41的发言:


。。。。。。Z版,俺是第一次高亮给色 谢谢提点。
看着好就给 当版主要有魄力
#15
有容就大2012-10-03 15:54
以下是引用zklhp在2012-10-3 15:50:13的发言:

看着好就给 当版主要有魄力

是啊 呵呵
不过俺们的魄力 来自于楼主的给力
#16
有容就大2012-10-03 16:09
回复 14楼 zklhp
Z版 我想你2个问题 。。。
1. 在一个程序中 能不能自定义两个堆栈?

程序代码:
stacka segment
  dw 100 dup(0)
stacka ends

stackb segment
  dw  100 dup(0)
stackb ends

2. 汇编能不能像C语言那么样 把一个工程分解为多个文件
如 xx.h + oo.c + oo1.c + oo2.c

到汇编就成了 xx.inc + oo.asm + oo1.asm + oo2.asm
如果能 他们之间怎么相互调用?
看了下MASMPlus 貌似新建的是一个MASM工程, 既然是工程应该能写入多个文件吧,
搞了这么久还在一个.asm里转悠。
#17
beyondyf2012-10-03 16:47
本来是串门的,结果到处见这小哥的文章(之前刚去了趟数据结构与算法版块)。

大整数的分治法运算倒不是什么新鲜东西,而且我决定回贴也主要是因为Z版说对了它的时间复杂度。

直接按你想的去计算并不比小学式计算来的快。

给你一点提示,要想改进算法的效率,还需要优化一下计算步骤。目前我能做到的是将时间复杂度降到O(N^log(3))

提个问题,不必回答给我。目前主流芯片的乘法、加法、移位指令的指令周期是多少?(多少个机器周期)


#18
zklhp2012-10-03 17:58
以下是引用有容就大在2012-10-3 16:09:28的发言:

Z版 我想你2个问题 。。。
1. 在一个程序中 能不能自定义两个堆栈?

stacka segment
  dw 100 dup(0)
stacka ends
 
stackb segment
  dw  100 dup(0)
stackb ends
2. 汇编能不能像C语言那么样 把一个工程分解为多个文件
如 xx.h + oo.c + oo1.c + oo2.c

到汇编就成了 xx.inc + oo.asm + oo1.asm + oo2.asm
如果能 他们之间怎么相互调用?
看了下MASMPlus 貌似新建的是一个MASM工程, 既然是工程应该能写入多个文件吧,
搞了这么久还在一个.asm里转悠。

第一个感觉可以但没试过

第二个肯定可以 最简单的方法就是主文件中include其他asm文件 这样就相当于自动整合成一个大的源文件 或者可以用模块化的方法 编译若干个obj文件链接到一块
#19
zklhp2012-10-03 18:14
以下是引用beyondyf在2012-10-3 16:47:59的发言:

本来是串门的,结果到处见这小哥的文章(之前刚去了趟数据结构与算法版块)。

大整数的分治法运算倒不是什么新鲜东西,而且我决定回贴也主要是因为Z版说对了它的时间复杂度。

直接按你想的去计算并不比小学式计算来的快。

给你一点提示,要想改进算法的效率,还需要优化一下计算步骤。目前我能做到的是将时间复杂度降到O(N^log(3))

提个问题,不必回答给我。目前主流芯片的乘法、加法、移位指令的指令周期是多少?(多少个机器周期)
目前主流芯片的乘法、加法、移位指令的指令周期是多少?(多少个机器周期)

具体的不好说 而且对于目前的CPU一条指令到底用多少时间跟很多东西有关 没法一概而论 简单的讲 对于我们用的X86等不是专门用来计算的芯片来说 加减 移位最快 可以认为就是1个指令周期 乘法的话 貌似在比较新的CPU上面 也就是得是core以上了 貌似也是1个周期 不过延迟大 也就是说 实际可能还是慢 延迟 如果能用一些东西消除的话可以没影响 不过一般还是有影响的罢。。

除法是大问题 老的CPU 除法大约要100个周期 现在的CPU也得大约50个 具体跟精度有关 但最快好像也得十来个 二十来个时钟周期 是比较慢的


#20
zklhp2012-10-03 18:18
以下是引用beyondyf在2012-10-3 16:47:59的发言:

本来是串门的,结果到处见这小哥的文章(之前刚去了趟数据结构与算法版块)。

大整数的分治法运算倒不是什么新鲜东西,而且我决定回贴也主要是因为Z版说对了它的时间复杂度。

直接按你想的去计算并不比小学式计算来的快。

给你一点提示,要想改进算法的效率,还需要优化一下计算步骤。目前我能做到的是将时间复杂度降到O(N^log(3))

提个问题,不必回答给我。目前主流芯片的乘法、加法、移位指令的指令周期是多少?(多少个机器周期)

顺便

欢迎大牛莅临指导
#21
有容就大2012-10-03 18:43
以下是引用zklhp在2012-10-3 17:58:16的发言:


第一个感觉可以但没试过

第二个肯定可以 最简单的方法就是主文件中include其他asm文件 这样就相当于自动整合成一个大的源文件 或者可以用模块化的方法 编译若干个obj文件链接到一块
PUSH和POP指令 后面都只有一个东西 也就是说另外一个是默认的
我就想如果有两个自定义栈 而SS:SP只有一个 那么压栈和出栈究竟指的是哪一个栈
如果一个程序不能同时定义有2个及以上的栈,那么又感觉一个栈不够用.


#22
有容就大2012-10-03 18:54
以下是引用beyondyf在2012-10-3 16:47:59的发言:

本来是串门的,结果到处见这小哥的文章(之前刚去了趟数据结构与算法版块)。

大整数的分治法运算倒不是什么新鲜东西,而且我决定回贴也主要是因为Z版说对了它的时间复杂度。

直接按你想的去计算并不比小学式计算来的快。

给你一点提示,要想改进算法的效率,还需要优化一下计算步骤。目前我能做到的是将时间复杂度降到O(N^log(3))

提个问题,不必回答给我。目前主流芯片的乘法、加法、移位指令的指令周期是多少?(多少个机器周期)

我感觉乘法 除法的指令周期是 4个机器周期, 加法和移位指令是1个机器周期。

顺便说下 难得杨大哥来汇编版交流,其实杨大哥在C版发起刷ACM的活动我本应当有所响应的 以前还心思浓厚呢 只是现在 搞汇编有一些时间 水平还比较菜 差强人意的做了个版主 只好多用点心思在这方面了。
还有就是在熟悉数据库方面的知识,偶尔去操作系统方面晃荡,都已经感觉力不从心了,你这段时间不在我
算法也放的差不多了,现在想拿起来也心有余力不足了,进去估计也是打酱油的份。真是不好意思啦。

对杨大哥的到来 表示欢迎 请多指教。
#23
zklhp2012-10-03 18:56
以下是引用有容就大在2012-10-3 18:54:59的发言:


我感觉乘法 除法的指令周期是 4个机器周期, 加法和移位指令是1个机器周期。

顺便说下 难得杨大哥来汇编版交流,其实杨大哥在C版发起刷ACM的活动我本应当有所响应的 以前还心思浓厚呢 只是现在 搞汇编有一些时间 水平还比较菜 差强人意的做了个版主 只好多用点心思在这方面了。
还有就是在熟悉数据库方面的知识,偶尔去操作系统方面晃荡,都已经感觉力不从心了,你这段时间不在我
算法也放的差不多了,现在想拿起来也心有余力不足了,进去估计也是打酱油的份。真是不好意思啦。

对杨大哥的到来 表示欢迎 请多指教。

除法最快也不可能是4个时钟周期 除非是专门的芯片。。
#24
zklhp2012-10-03 18:57
以下是引用有容就大在2012-10-3 18:43:41的发言:

PUSH和POP指令 后面都只有一个东西 也就是说另外一个是默认的
我就想如果有两个自定义栈 而SS:SP只有一个 那么压栈和出栈究竟指的是哪一个栈
如果一个程序不能同时定义有2个及以上的栈,那么又感觉一个栈不够用.

定义多个应该是可以 但不管有几个同时也只能用一个 由ss:sp指定
#25
有容就大2012-10-03 18:59
以下是引用zklhp在2012-10-3 18:56:33的发言:


除法最快也不可能是4个时钟周期 除非是专门的芯片。。

貌似一个机器周期包含若干个时钟周期?
#26
zklhp2012-10-03 19:00
以下是引用有容就大在2012-10-3 18:59:46的发言:


貌似一个机器周期包含若干个时钟周期?

啥是机器周期啊 没听说过 不懂了。。
#27
有容就大2012-10-03 19:01
以下是引用zklhp在2012-10-3 18:57:07的发言:


定义多个应该是可以 但不管有几个同时也只能用一个 由ss:sp指定

哦 这样倒是对程序的运行效率有所提升 不过要注意多次改变SS:SP 呵呵。
1