大整数运算C语言实现C语言大作业报告+源码
大整数运算C语言实现C语言大作业报告+源码
一、设计高精度无符号大整数计算
(以1为存储单位)
1.1 需求陈述
对数值很大、精度很高的数进行高精度大整数计算是一类十分常见的问题。但由于C语言中数据类型受数据长度和范围限制,普通数学计算很难实现此类问题,为尝试解决这个问题,专门设计一个C语言程序用于无符号大整数的计算,实现无符号大整数的一般计算和比较功能。
1.2 需求分析
1.2.1 功能分析
表1 程序功能分析
项目功能分析
以字符串形式接受
数据接收反转字符串函数Invert()
用Translate()将字符串翻译为整形数组
分别用BigN_cmp_low()和BigN_cmp_High()对数据进行比较
加法BigN_Add() //从a[1]对数组进行比较,传入两个数组及其大小以及需要从第几位开
始比较减法BigN_Min() 数据
运算低位减法BigN_Min_low(),在未反转的情况下计算 int
BigN_cmp_High(int *, int *, int , int ); BigN
乘法BigN_Mul() //从a[n]对数组进行比较,传入两个数组及其大小
除法BigN_Div()
反转整形数组InvertInt()
从前面删减多余的零Del_zero_low() 运算辅助
函数从末尾删减多余的零Del_zero_High()
获取两个数的最大值Get_MAX()
1
1.2.2 数据分析
该程序可用于计算无符号大整形数据计算,最多可计算长度为200位(即10的200次方大小)的数据,但在原代码中可以随数据需求改变最大长度。该)的情况。由于数据类型程序中所有运算和比较均考虑到了输入前导0(例0001 限制,该程序未加入小数计算和负数计算,除法结果中只分别计算商和余数。
1.2.3 技术约束
本程序已在code blocks下编译通过。
1.3 总体设计
1.3.1 全局数据结构
本程序中数据采取以个位数字为单位存入整形数组,在数据计算和比较中对单个数组单元进行操作。采用整形数组存储,主要优点为可以在该程序的基础上进行改进,使字符串中每四个数字或更多存入一个数组单元中(如程序二)。
1.3.2 函数设计
A(数据的接收
1(反转字符串函数 Invert()
函数原型:void Invert (char * , int ); 功能: 反转字符串,传入字符串首地址和长度
在加法、减法、乘法计算中必须先对字符串进行反转,是字符串整体逆转,但不改变字符串长度。
2. 翻译字符串函数 Translate()
函数原型:void Translate (char *, int *, int *);
功能:将字符串翻译为数组,传入字符串和数组及数组大小的地址
B. 数据运算
1. 比较函数 BigN_cmp_low()和BigN_cmp_High()
函数原型:int BigN_cmp_low (int *, int *, int , int , int );
2
和int BigN_cmp_High(int *, int *, int , int ); 功能:对整形数组分别进行地位和高位比较,即从开头和结尾开始进行比较。
实现步骤:先将数组中不必要的零去掉,然后记下位数,对位数进行比较,最后从原始数据
最高位进行比较,逐步往下比较,若前面小于后面,则返回值为1,;若后面小于前面,则
返回-1;若相等,则返回值为0.
2. 加法BigN_Add()
函数原型:void BigN_Add (int *, int *, int , int *); 功能:高精度加法,传入反转后的数组及其大小的最大值,和结果数组的首地址。
实现步骤:依次将所需计算的两个数组及其位数的最大值传入函数,对两个函数每一位进行
加法存入结果中,对满十的结果进行进位,然后对该位进行对十取余存入结果。
实现代码:for(i = 1; i <= max; i++)
{
res[i] += num1[i] + num2[i];
res[i+1] += res[i] / 10;
res[i] %= 10;
}
3. 减法BigN_Min()和低位减法BigN_Min_low()
函数原型:void BigN_Min (int *, int *, int , int *);
void BigN_Min_low(int *, int *, int , int , int *);;
功能: 高精度减法,传入反转后的数组及其大小的最大值,和结果数组的首地址。
高精度低位减法,传入未反转的数组及其大小的最大值,和结果数组的首地址。
实现步骤:依次将所需计算的两个数组及其位数的最大值传入函数,对两个函数每一位进行
减法存入结果中,对减不着的进行借位,然后对该为进行对十取余存入结果。
实现代码:for(i = 1; i <= max; i++)
if(num1[i] >= num2[i])
res[i] += num1[i] - num2[i];
else
{
res[i] += num1[i] + 10 - num2[i];
num1[i+1] -= 1;
}
4. 乘法BigN_Mul()
函数原型:void BigN_Mul (int *, int *, int , int , int *); 功能:高精度乘法,传入反转后的数组及其大小,和结果数组的首地址。
实现步骤:对两个函数的每一位进行乘法,然后对于大于10的结果进行进位操作。由于该
程序中所有数组均从1开始存,故运算结果从2开始存。
实现代码:for(i = 1;i <= bit1; i++)
for(j = 1;j <= bit2; j++)
{
res[i+j] += num1[i] * num2[j];
res[i+j+1] += res[i+j] / 10;
3
res[i+j] %= 10;
}
5. 除法BigN_Div()
函数原型:void BigN_Div (int *, int *, int , int , int *, int *, int *, int *);
功能:高精度除法,传入未反转的数组及其大小、商的首地址、余数的首地址、商的位数、
余数的位数.
实现步骤:将未经反转的数组传入,从0开始做个操作,循环利用比较和减法,若余数大
于除数,则进行减法调用,此处用到的减法为低位减法.
实现代码:*res_bit = 1;
for(i = 1;i <= bit1; i++)
{
Del_zero_low(mod,bit_mod);//对mod低位去零
if(BigN_cmp_low(mod,num2,*bit_mod,bit2,1) > 0)//mod 为真 { (*bit_mod)++; mod[*bit_mod] = num1[i];//将num1逐个复制给mod } while(BigN_cmp_low(mod,num2,*bit_mod,bit2,1) <= 0)// mod> num2 { for(j = 1;j <= (*bit_mod); j++) temp[j] = 0;//每次将余数的结果置为 0 BigN_Min_low(mod,num2,(*bit_mod),bit2,temp); (res[*res_bit])++; for(j = 1;j <= (*bit_mod);j++) mod[j] = 0;//mod 置零 Del_zero_low(temp,bit_mod);//对 mod 低位去零,防止如“001”的 结果 for(j = 1; j<=(*bit_mod); j++) mod[j] = temp[j];//将mod值给mod,做下一次计算 flag = 1; } if(flag == 1)//只有经过减法之后才开始++,保证结果从 res[1] 开始存(*res_bit)++; } C. 运算辅助函数 1. 反转整形数组InvertInt() 函数原型:void InvertInt (int *, int ); 功能:反转数组,传入数组首地址和大小.将数组的存储顺序进行对调,实现整形数组的反转。 4 2. 删减多余的零Del_zero_low()和Del_zero_High() 函数原型:void Del_zero_low (int *, int *); void Del_zero_High(int *, int *); 功能:从a[1]开始去零,结果为去零后的数组及其大小;从a[n]开始去零,结果为去零后的数组及其大小,用于比较两个数的大小和控制输出时被调用。传入整形数组和位数的地址,对整形数组和位数进行操作。 3. 获取两个数的最大值Get_MAX() 函数原型:int Get_MAX (int , int ); 功能:获取两个数的最大值,返回值为大的那个数。 实现代码:return a>b?a:b; 1.4 设计思想说明 该程序中所有大整型无符号数据的运算均采用模拟手算的方法,对单个数字进行操作,以实现大整型运算。为程序运行更加高效,调用函数过程中传输多个参数,若将该程序作为模板,则可省略其中某些参数,使调用更方便。 1.5 测试结果说明 主界面: 测试加法: 5 图一图二测试减法: 图一图二测试乘法: 图一图二 6 图三 测试除法: 图一图二 图三图四 测试比较:(可采用程序二中的Del_zero_Str ()函数进行对多余0的删减) 7 图一图二 注:以上数据均为程序在Code Blocks 的写入文本的运行结果,且该结果都通过了验证。 1.6 完整代码 详见程序文件BigN.c。 二、设计高精度无符号大整数计算 (以10000为存储单位) 注:由于本程序在前一程序基础上建立,故本程序主要介绍与前一程序的不同。 2.1 需求陈述 对数值更大、精度更高的数进行高精度大整数计算是基于上一程序的又一问题。但由于C语言中数据类型受数据长度和范围限制,前一程序很难实现更高位的运算,为尝试解决这个问题,在前一程序的基础上对无符号大整数的计算进行了改进实现无符号大整数的一般计算和比较功能。而且改进后的程序运行更为高效。 2.2 需求分析 2.2.1 功能分析 8 表1 程序功能分析 项目功能分析 用Wan_TransGT ()将字符串翻译为整形数组数据接收 传入整形n,计算10的n次方 IntPow_ten () Wan 运算辅助从前面删减对字符串多余的‘0’Del_zero_Str () BigN 函数 不再使用从末尾删减多余的零Del_zero_High() 注:由于以万为存储单位的程序对除法的计算效率过低,故不采用除法。 2.2.2 数据分析 该程序可用于计算无符号大整形数据计算,最多可计算长度为200位(即10000的200次方大小)的数据,但在原代码中可以随数据需求改变最大长度。该程序中所有运算和比较均考虑到了输入前导0(例0001)的情况。由于数据类型限制,该程序未加入小数计算和负数计算。 2.2.3 技术约束 本程序已在code blocks下编译通过。 2.3 总体设计 2.3.1 全局数据结构 本程序中数据采取以10000为单位存入整形数组,在数据计算和比较中对单个数组单元进行操作。 2.3.2 函数设计 A(数据的接收 1(反转字符串函数 Invert() 同上。 9 2. 翻译字符串函数 Wan_TransGT () 函数原型:void Wan_TransGT(char *str,int *num, int *bit) 功能:将字符串翻译为数组,传入字符串和数组及数组大小的地址 实现代码: if(strlen(str)%4 != 0) for(i = 0; i < (strlen(str)/4+1)*4; i++) { if(i%4==0) (*bit)++; if(str[i] != 0) num[*bit] += (str[i]-'0') * IntPow_ten(i%4); } else for(i = 0; i < strlen(str); i++) { if(i%4==0) (*bit)++; if(str[i] != 0) num[*bit] += (str[i]-'0') * IntPow_ten(i%4); } B. 数据运算 1. 比较函数 BigN_cmp_low()和BigN_cmp_High() 同上. 2. 加法BigN_Add() 函数原型:void BigN_Add (int *, int *, int , int *); 功能:高精度加法,传入反转后的数组及其大小的最大值,和结果数组的首地址。 实现步骤:依次将所需计算的两个数组及其位数的最大值传入函数,对两个函数每一位进行 加法存入结果中,对满10000的结果进行进位,然后对该位进行对10000取余存入结果。实现代码:for(i = 1; i <= max; i++) { res[i] += num1[i] + num2[i]; res[i+1] += res[i] / 10000; res[i] %= 10000; } 3. 减法BigN_Min()和低位减法BigN_Min_low() 函数原型:void BigN_Min (int *, int *, int , int *); 功能: 高精度减法,传入反转后的数组及其大小的最大值,和结果数组的首地址。 实现步骤:依次将所需计算的两个数组及其位数的最大值传入函数,对两个函数每一位进行 减法存入结果中,对减不着的进行借位,然后对该为进行对十取余存入结果。 实现代码:for(i = 1; i <= max; i++) if(num1[i] >= num2[i]) 10 res[i] += num1[i] - num2[i]; else { res[i] += num1[i] + 10000 - num2[i]; num1[i+1] -= 1; } 4. 乘法BigN_Mul() 函数原型:void BigN_Mul (int *, int *, int , int , int *); 功能:高精度乘法,传入反转后的数组及其大小,和结果数组的首地址。 实现步骤:对两个函数的每一位进行乘法,然后对于大于10000的结果进行进位操作。由 于该程序中所有数组均从1开始存,故运算结果从2开始存。 实现代码:for(i = 1;i <= bit1; i++) for(j = 1;j <= bit2; j++) { res[i+j] += num1[i] * num2[j]; res[i+j+1] += res[i+j] / 10000; res[i+j] %= 10000; } 5. 除法BigN_Div() 函数原型:void BigN_Div (int *, int *, int , int , int *, int *, int *, int *); 功能:高精度除法,传入未反转的数组及其大小、商的首地址、余数的首地址、商的位数、 余数的位数. 实现步骤:将未经反转的数组传入,从0开始做个操作,循环利用比较和减法,若余数大 于除数,则进行减法调用,此处用到的减法为低位减法. C. 运算辅助函数 1.反转整形数组InvertInt() 同上。 2.删减多余的零Del_zero_str() 函数原型:void Del_zero_str (char *); 功能:从str[1]开始去零,结果为去零后的字符串;用于比较两个数的大小时被调用。 3.获取两个数的最大值Get_MAX() 同上。 2.4 设计思想说明 该程序中所有大整型无符号数据的运算均采用模拟手算的方法,对单个四位数字进行操 作,以实现大整型运算。为程序运行更加高效,调用函数过程中传输多个参数,若将该程序 11 作为模板,则可省略其中某些参数,使调用更方便。 2.5 测试结果说明 主界面截图 测试加法: 图一图二测试减法: 图一图二12 测试乘法: