[分享]制作高效的极大数乘法和加法

瑞卡哥哥 2013-05-03 02:31:24
加精
看了很多人写的大数相乘的代码,感觉纯粹意义的计算乘法让人很是崩溃,既然乘法竖式的计算原本就是多个积相加,为什么还要搞的那么复杂呢。
原理如下:

1 2 3
* 5 6
------------------------
7 3 8
+ 6 1 5
------------------------
= 6 8 8 8

那么就是说只需要计算每位的积即可:即123*6=738;123*5=615;738+625*10=6888;
那么加法的效率大家都能做到很高效。这样大数的乘法就变成了大数乘以一个个位数了。
so:
传送去下载
博客看代码
...全文
4343 110 打赏 收藏 转发到动态 举报
写回复
用AI写文章
110 条回复
切换为时间正序
请发表友善的回复…
发表回复
aqua2013 2014-05-30
  • 打赏
  • 举报
回复
你这个怎么能叫大数乘法呢? 大数就选多字节数嘛,最适合计算机处理的
  • 打赏
  • 举报
回复
还在首页啊,这帖子到底是谁置顶的? 和c#有仇?
「已注销」 2013-05-28
  • 打赏
  • 举报
回复
我局的该算法很简单,就按照传统意义的笔算法相加即可!
绿色夹克衫 2013-05-28
  • 打赏
  • 举报
回复
LZ来这里试试自己的乘法效率如何吧?支持C#。看看10w位的乘法要算多少时间? http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1028
forgetsam 2013-05-24
  • 打赏
  • 举报
回复
这个帖子留在首页,是为了黑.net的吗,还是说已经不用黑了,.net程序员就是这样?
星小野 2013-05-24
  • 打赏
  • 举报
回复
引用 楼主 zhouqinghe24 的回复:
看了很多人写的大数相乘的代码,感觉纯粹意义的计算乘法让人很是崩溃,既然乘法竖式的计算原本就是多个积相加,为什么还要搞的那么复杂呢。 原理如下: 1 2 3 * 5 6 ------------------------ 7 3 8 + 6 1 5 ------------------------ = 6 8 8 8 那么就是说只需要计算每位的积即可:即123*6=738;123*5=615;738+625*10=6888; 那么加法的效率大家都能做到很高效。这样大数的乘法就变成了大数乘以一个个位数了。 so: 传送去下载 博客看代码
编码的奥秘,基于加法的2进制减法实现
  • 打赏
  • 举报
回复
我就笑笑,不说话。
liangbch 2013-05-16
  • 打赏
  • 举报
回复
回101楼。我还真没有开始研究Schonhage-Strassen这个算法呢。目前我仍然停留在优化低阶函数阶段。
无心人 2013-05-16
  • 打赏
  • 举报
回复
宝宝同学,你弄明白Schonhage-Strassen了么?
liangbch 2013-05-15
  • 打赏
  • 举报
回复
大数乘法是个很重要,很复杂的算法,我学习它20多年,至今没有听说过既高效又简单直观的算法。 先不说大牛发明的Schonhage-Strassen算法 也不说 Fourier transform 算法 或者他的变种快速数论变换算法。 也不说 Toom–Cook 插值说法, 也不说分治法中最简单Karatsuba算法 单就众所周知的硬乘法,也叫long 乘法,有时也叫做grade-school 乘法,就是我们在小学是使用纸笔的乘法,就有好多学问。 1. 基的选择 菜鸟一般选择10进制,高手选择1000000000进制(每个整数表示9位10进制数)。对于2个900位数的乘法,前者需要 900 * 900=81万次乘法,后者需要100*100=1万次乘法,哪个更快,就不需解释了吧。 2. 以行为主做乘法还是以列为主做乘法。 菜鸟一般选择以行为主,高手选择以列为主。对于2个长度为n个单位的乘法,前者需要做n*n次除法来计算进位,后者需要2×n*n/k次除法来计算进位,k和基的选择有关。当基为1000000000,k取18,后者所需的除法次数仅仅是前者的1/9 3. 使用MMX/SSE2还是ALU指令做乘法,在现代计算机,SSE2/MMX速度比ALU指令更快,使用SSE2/MMX指令可显著提高计算速度。 注:学习它20多年是指:是指20年前,我在大学一年级刚学pascal时,还没有学到数组呢,就写了一个多位数乘以多位数的乘法。现在仍在致力于写一个这个星球上最快的大数库,超过GMP。 by the way, 度量程序性能好坏的指标是时钟周期,而不是很快,一眨眼,马上.如果你的电脑的主频是1G,使用你的程序,计算1千万位数乘以一个1位数,所需时间是1秒。那么,你的程序在你的这种类型的CPU的性能为 1* 10^9/1千万位=100/位,换言之,每计算1位10进制数,耗费时间是100个周期。
u010674732 2013-05-13
  • 打赏
  • 举报
回复
算法没有效率,有什么意义么
lovejiew 2013-05-13
  • 打赏
  • 举报
回复
这叫什么东西....
爱在今世 2013-05-13
  • 打赏
  • 举报
回复
lz有没有用过System.Diagnostics.Stopwatch来试验一下速度快了没有?测试算法的效率还不就行他得出正确结果的时间嘛。用System.Diagnostics.Stopwatch来计算代码运行的时间,多来几次求个平均数看看到底快了没
u010678158 2013-05-13
  • 打赏
  • 举报
回复
算法看起来很复杂啊!
china_jeffery 2013-05-13
  • 打赏
  • 举报
回复
明显不符合大数相乘的初衷。举个例子: A*B=C A = 一个很大的数,这个数已经不能用计算机数据类型的来表示,这时还怎么计算乘积
vcorange 2013-05-12
  • 打赏
  • 举报
回复
以前也是用c# list 做了个大数 四则运算,可以无限制计算长度(除非内存不足),后来源码丢了,到现在都不会计划再次重写...
最美的词 2013-05-11
  • 打赏
  • 举报
回复
不知道如何去评价你的这个算法。但是我想,你的这个方法是很容易想到的,为什么前人没有大谈特谈这个方法,应该有其它的问题,比如空间复杂度
  • 打赏
  • 举报
回复
咦,难道最有效率的方式不是NUM1循环加上NUM2次?
卿文天 2013-05-10
  • 打赏
  • 举报
回复
真心感觉这个没效率,特别是对大数(9999999*999999)=?
crystaldn 2013-05-10
  • 打赏
  • 举报
回复
优化中间的循环,快了一些 public static string LongNumberMul(string s1, string s2) { //初始化数据 int len1 = s1.Length; int len2 = s2.Length; int[] Num1 = new int[len1]; int[] Num2 = new int[len2]; for (int i = 0; i < len1; i++) Num1[i] = CharToInt(s1[len1 - 1 - i]); for (int i = 0; i < len2; i++) Num2[i] = CharToInt(s2[len2 - 1 - i]); lResult.Clear(); /*/ for (int i = 0; i < len1; i++) { for (int j = 0; j < len2; j++) { SingleAdd(Num1[i] * Num2[j],i+j); } } /*/ for (int i = 0; i <= len1 + len2 - 2; i++) { int temVal = 0; for (int j =(i>=len2?i-len2 + 1:0);j<len1&&j<=i;j++) { temVal += Num1[j]*Num2[i-j]; } SingleAdd(temVal,i); } StringBuilder sb = new StringBuilder(); for (int i = 0; i < lResult.Count; i++) { sb.Insert(0, lResult[i]); } sb.Insert(0," "); sb.Insert(0, times); return sb.ToString(); }
加载更多回复(77)

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧