大数相乘的一种思路(2012年软件设计大赛的启思)
2012-04-10 22:55
399 查看
做过不少ACM试题都涉及到大数(超过32位int)的运算,有加法、阶乘的之类的。2012年的软件大赛上见到一种独特的思路,故而记之如下:
大数乘法
对于 32 位字长的机器,大约超过 20 亿,用 int 类型就无法表示了,我们可以选择 int64 类型,但无论怎样扩展,固定的整数类型总是有表达的极限!如果对超级大整数进行精确运算呢?
一个简单的办法是: 仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法” 。如下图原理:
表示了分块乘法的原理。可以把大数分成多段(此处为 2 段)小数,然后用小数的多次运算组合表示一个大数。可以根据 int 的承载能力规定小块的大小,比如 要把 int 分成 2 段,则小块可取 10000 为上限值。注意,小块在进行纵向累加后,需要进行 进位校正。 以下代码示意了分块乘法的原理(乘数、被乘数都分为 2 段) 。
具体实现代码如下:
参考原理图还是很容易理解的
void bigmul(int x,
int y, int r[])
{
int base =
10000;
int x2 = x / base;
int x1 = x % base;
int y2 = y / base;
int y1 = y % base;
int n1 = x1 * y1;
int n2 = x1 * y2;
int n3 = x2 * y1;
int n4 = x2 * y2;
r[3] = n1 % base;
r[2] = n1 /
base + n2 % base + n3 %
base;
r[1] = n2 / base + n3 / base + n4 % base;// 填空,参考原理图很容易理解的
r[0] = n4 /
base;
r[1] += r[2] / base;// 填空
r[2] = r[2] %
base;
r[0] += r[1] /
base;
r[1] = r[1] %
base;
}
int main(int argc,
char* argv[])
{
int x[] = {0,0,0,0};
bigmul(87654321,
12345678, x);
printf("%d%d%d%d\n", x[0],x[1],x[2],x[3]);
return 0;
}
大数乘法
对于 32 位字长的机器,大约超过 20 亿,用 int 类型就无法表示了,我们可以选择 int64 类型,但无论怎样扩展,固定的整数类型总是有表达的极限!如果对超级大整数进行精确运算呢?
一个简单的办法是: 仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法” 。如下图原理:
表示了分块乘法的原理。可以把大数分成多段(此处为 2 段)小数,然后用小数的多次运算组合表示一个大数。可以根据 int 的承载能力规定小块的大小,比如 要把 int 分成 2 段,则小块可取 10000 为上限值。注意,小块在进行纵向累加后,需要进行 进位校正。 以下代码示意了分块乘法的原理(乘数、被乘数都分为 2 段) 。
具体实现代码如下:
参考原理图还是很容易理解的
void bigmul(int x,
int y, int r[])
{
int base =
10000;
int x2 = x / base;
int x1 = x % base;
int y2 = y / base;
int y1 = y % base;
int n1 = x1 * y1;
int n2 = x1 * y2;
int n3 = x2 * y1;
int n4 = x2 * y2;
r[3] = n1 % base;
r[2] = n1 /
base + n2 % base + n3 %
base;
r[1] = n2 / base + n3 / base + n4 % base;// 填空,参考原理图很容易理解的
r[0] = n4 /
base;
r[1] += r[2] / base;// 填空
r[2] = r[2] %
base;
r[0] += r[1] /
base;
r[1] = r[1] %
base;
}
int main(int argc,
char* argv[])
{
int x[] = {0,0,0,0};
bigmul(87654321,
12345678, x);
printf("%d%d%d%d\n", x[0],x[1],x[2],x[3]);
return 0;
}
相关文章推荐
- 一种新的思路设计远控去改造小白虎远程控制软件
- 软件系统设计的思路
- 软件系统设计思路
- Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程
- 2011年 - 第三届360软件大赛题目 - 第二题 完全利用helper.dll设计ROP
- 软件自动升级程序的设计思路
- 全国软件设计大赛
- 桌面软件底层日志的一种改进设计
- 2012年第三届蓝桥杯全国软件大赛c++预赛 题目及参考答案
- 软件系统设计思路
- 全国软件设计大赛--代码设计
- 2011届蓝点杯全国软件设计与开发大赛 选拔赛获奖名单
- [提供源码下载]在大型软件中用Word做报表:书签的应用(提供一种思路)
- 小弟和同学的作品大家给评价评价 《交警移动警务》-awaken团队 济南职业学院 2012齐鲁软件设计大赛作品,http://v.youku.com/v_show/id_XNDY2MTY1ODc2.
- 诺基亚手机软件设计大赛
- Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程
- 跨国际链路的数据服务系统架构设计的一种实现思路
- 全国软件设计大赛题目-逻辑推断题目
- 桌面软件底层日志的一种改进设计
- 一种全新的软件界面设计方法 (一)