C语言中超大整数乘法运算.docx

.C 语言中超大整数乘法运算在计算机中,长整型 long int 变量的范围是 -2147483648 至 2147483647 ,因此若用长整型变量做乘法运算,乘积最多不能超过 10 位数。即便用双精度型 double 变量,也仅能保证 16 位有效数字的精度。在某些需要更高精度的乘法运算的场合,需要用别的办法来实现乘法运算。比较容易想到的是做多位数乘法时列竖式进行计算的方法,只要写出模拟这一过程的程序,就能实现任意大整数的乘法运算。经过查阅资料,找到一种更易于编程的方法,即“列表法”。下面先介绍“列表法”例如当计算 8765 x 234时,把乘数与被乘数照如下列出,见表1 把表 1 中的数按图示斜线分组(横纵坐标和相等的数分为一组),把每组数的累加起来所得的和记在表格下方,见表 2 从最低位的 20 开始,保留个位数字“0 ”,把个位以外的数“2 ”进到前一位;把39次低位的加上低位进上来的2 得 41 ,保留个位数字“1 ”,把“4 ”进到前一位;以此类推,直至最高位的 16 ,16 加上低位进上来的4 得 20 ,保留“0 ”,把2 进到最高位,得乘积答数2051010 。根据以上思路就可以编写C 程序了,再经分析可得1、一个 m 位的整数与一个n 位的整数相乘,乘积为mn-1位或 mn 位。2、程序中,用三个字符数组分别存储乘数、被乘数与乘积。由第1 点分析知,存放乘积的字符数组的长度应不小于存放乘数与被乘数的两个数组的长度之和。3、可以把第二步“计算填表”与第三四步“累加进位”放在一起完成,可以节省存储表格2 所需的空间。4、程序关键部分是两层循环,内层循环累计一组数的和,外层循环处理保留的数字与进位。编写的程序如下define MAXLENGTH 1000include stdio.hinclude string.hvoid computechar *a, char *b, char *c;void mainvoidchar aMAXLENGTH, bMAXLENGTH, cMAXLENGTH * 2;puts multiplier ;getsa;puts multiplicand ;getsb;computea, b, c;putsAnswer ;putsc;getchar;void computechar *a, char *b, char *cint i, j, m, n;long sum, carry;m strlena - 1;n strlenb - 1;for i m; i 0; iai - 0;for i n; i 0; ibi - 0;cm n 2 0;carry 0;for i m n; i 0; i /* i为坐标和 */sum carry;if j i - m 0j 0;for ; ji jn; j /* j为纵坐标 */sum ai-j * bj; /*累计一组数的和*/ci 1 sum 10 0; /*算出保留的数字*/carry sum / 10; /*算出进位 */if c0 carry0 0 /* if no carry, */c0 040; /* c0 equals to space */效率分析用以上算法计算 m 位整数乘以 n 位整数,需要先进行 m x n 次乘法运算,再进行约 m n 次加法运算和 m n 次取模运算 实为整数除法 。把这个程序稍加修改,让它自己产生乘数与被乘数,然后计算随机的 7200 位整数互乘,在 Cyrix 6x86 pr166 机器的纯 DOS 方式下耗时 7 秒用 Borland C3.1 编译 。经过改进,此算法效率可以提高约9 倍。注意到以下事实 8216547 x 96785 将两数从个位起,每 3 位分为节,列出乘法表,将斜线间的数字相加;8 216 54796 785将表中最后一行进行如下处理从个位数开始,每一个方格里只保留三位数字,超出1000 的部分进位到前一个方格里;所以 8216547 x 96785 795238501395也就是说我们在计算生成这个二维表时,不必一位一位地乘,而可以三位三位地乘;在累加时也是满 1000 进位。这样,我们在计算m 位整数乘以 n 位整数,只需要进行m x n / 9次乘法运算,再进行约 m n / 3次加法运算和 m n /3次取模运算。总体看来,效率约是前一种算法的 9 倍。有人可能会想既然能够三位三位地乘,为什么不4 位 4 位甚至 5 位 5 位地乘呢那不是可以提高 16 乃至 25 倍效率吗听我解来本算法在累加表中斜线间的数字时,如果用无符号长整数 范围 0 至 4294967295 作为累加变量,在最不利的情况下 两个乘数的所有数字均是9 ,能够累加约 4294967295/999*9994300次,也就是能够准确计算任意两个均不超过12900 每次累加的结果 值 三位,故 4300*312900位的整数相乘。如果4 位 4 位地乘,在最不利的情况下,能够累加约4294967295/9999*999943次,仅能够确保任意两个不超过172 位的整数相乘,没有什么实用价值,更不要说5 位了。请看改进后的算法的实例程序该程序随机产生两个 72xx 位的整数,把乘数与积保存在 result.txt 中。在 Borland C 3.1 中用BCC -3 -O2 -G -mh -Z -f287 -pr -T- dashu.cpp编译生成的 文件在 Cyrix 6x86 pr166的机器上运行耗时0.82 秒。程序 2 清单includeconio.hincludestring.hincludestdio.hincludestdlib.hincludetime.hdefine N 7200 作 72xx 位的整数乘法int maxint,int,int;int initarrayint a;void writeint a,int l;FILE *fp;void mainint a50000,b50000,k100010; 声明存放乘数、被乘数与积的数组clock_t start, end; 声明用于计时的变量unsigned long c,d,e; 声明作累加用的无符号长整数变量 int i,j,la,lb,ma,mi,p,q,t; 声明其它变量 randomize; 初始化随机数lainitarraya; 产生被乘数,并返回其长度lbinitarrayb; 产生乘数,并返回其长度iflalb 如果被乘数长度小于乘数,则交换被乘数与乘数plblalbla;for q0;qp;q 交换被乘数与乘数taq,aqbq,bqt;tla,lalb,lbt; 交换被乘数的长度与乘数的长度start clock;开始计时cd0; 清空累加变量,其中C 用于累加斜线间的数, d 用作进位标志forilalb-2;i0;i 累加斜线间的数, i 为横纵坐标之和cd; 将前一位的进位标志存入累加变量cmamax0,i-la1,i-lb1; 求累加的下限miila-1la-1i; 求累加的上限forjma;jmi;j 计算出横纵坐标之和为i 的单元内的数 ,并累加到 C 中clongaj*bi-j;dc/1000; 求进位标志ifc999c1000; 取 c 的末三位kic; 保存至表示乘积的数组kek01000*d; 求出乘积的最高位end clock;停止计时fp result.txt, w; 保存结果到 result.txtprintfnThe elapsed time was 3.4fn, end - start / CLK_TCK; 打印消耗的时间fprintffp,d,a0; 打印被乘数最高位writea,la; 打印被乘数其他位fprintffp,d,b0; 打印乘数最高位writeb,lb; 打印乘数其他位fprintffp,ld,e; 打印乘积最高位writek,lalb-1; 打印乘积其他位fclosefp;maxint a,int b,int cint d;dabab;return dcdc;int initarrayint aint q,p,i;qNrandom100;ifq30pq/3;elsepq/31;fori0;ip;iairandom1000;ifq30a0100random900;ifq32a010random90;ifq31a01random9;return p;void writeint a,int lint i;char string10;fori1;il;iitoaai,string,10;if strlenstring1fprintffp,00;if strlenstring2fprintffp,0;fprintffp,s,string;ifi1250fprintffp,n;fprintffp,n;fprintffp,n;.

用C语言计算超大乘法,C语言中超大整数乘法运算.docx相关推荐

  1. python语言的取余运算符_Python 中用于整数除法取余的运算符是()_学小易找答案...

    [填空题]隐球菌病多由()传播. [单选题]下列选项中,哪一个符号是管道符号. ( ) [多选题]可采用分批法计算产品成本的企业有( ) [填空题]现有字符串 s="1234567" ...

  2. c语言横纵坐标乘法,C语言 · 猜算式 · 乘法竖式

    题目:猜算式 你一定还记得小学学习过的乘法计算过程,比如: 273 x   15 ------ 1365 273 ------ 4095 请你观察如下的乘法算式 *** x   *** ------- ...

  3. c语言金字塔输出乘法表,python中打印金字塔和九九乘法表的几种方法

    # 打印九九乘法表 for i in range(1,10): for j in range(1,i+1): # x=i*j # print(i,'*',j,'=',x,end=' ') print( ...

  4. C语言计算级数fun,c语言编程 编写函数fun(),它的功能是:计算和输出下列级数的和....

    用C语言编程,已知f(x)=(1+x^2),编写函数用梯形法计算f(x)在区间[a,b]上的定积分 #includevoidmain(){doublei,j;doublea,b,c=0;printf( ...

  5. c语言横纵坐标乘法,C语言:有横纵标题的九九乘法表

    学习c语言已经不少时间了,今天算是写出了这短短的数周学习时间里面,自己觉得最喜欢的代码.这是一道来自<明解c语言>这本书的练习.难度不大,我的写法应该不是最优解,但是输出的结果真的是很优美 ...

  6. c语言pi的乘法,c语言 根据公式求出π的近似值。

    共回答了10个问题采纳率:80% #includedouble powi(double num, int multi) { double r = 1.0; int i; for (i = 0; i & ...

  7. c语言实现稀疏矩阵乘法,C语言实现稀疏矩阵

    本文实例为大家分享了C语言实现稀疏矩阵的具体代码,供大家参考,具体内容如下 #include "stdio.h" #define maxsize 10 typedef struct ...

  8. c语言计算24游戏,C语言解24点游戏程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 前几天在微博上看到24点的游戏,6 6 6 10.算了很久是在算不出来,最后我想我何不写一个小程序解决它?说做就做,我刚开始的想法很简单,就是列举4个数的 ...

  9. 用c语言计算高考成绩,C语言计算距离高考剩余时间

    每年6月6日定为高考,输入日期:xxxx.xx.xx,若没到6月6日,则算距离今年的,否则算明年的. #include #define uint unsigned int /*月份天数,1月31,2月 ...

最新文章

  1. 用leangoo怎么添加泳道,拖拽移动泳道?
  2. Django开发实战
  3. 安装Ubuntu 14.04后要做的5件事情
  4. wireshark 配 filddler 手机抓包
  5. Spring 运用 pointcut 和 advisor 对特定的方法进行切面编程
  6. 深度解密之HDU3826(Square free number)
  7. Android中的Intent和Intent-filter总结
  8. X210串口配置与stdio移植
  9. Selenium 中文手册
  10. java中,将string 转化成long
  11. Python机器学习:PCA与梯度上升001什么是PCA
  12. 【机器学习】鸢尾花数据探索
  13. Lucene中的一些基本概念
  14. IIS经典模式和集成模式的区别
  15. 截取一段字符串中,两个指定字符串中间的字符串
  16. win10为单个网卡配置多个IP地址
  17. 编码器正反转识别方法
  18. 考拉nbsp;PASCALnbsp;解题报告
  19. 解决冲突后,git merge --continue 时 lint不通过
  20. Spark随笔(三):straggler的产生原因

热门文章

  1. Linux驱动开发(三)---设备树
  2. 深交所几大平台及其处理业务介绍
  3. Python爬取微信小程序数据[使用Charles手机抓包获取微信小程序的请求]
  4. 札记【3】间歇性丧失斗志
  5. javascript 要点概要
  6. 华硕笔记本学计算机,2017新款华硕笔记本电脑大学生用
  7. 手绘漫画初学者如何一步步学手绘漫画
  8. OpenCV 图像边缘提取(三)—— Laplance算子提取边缘原理及OpenCV API使用(C#)
  9. 怎么压缩PDF大小?说几个思路
  10. 电路板去板边—V-Cut分板机注意事项