大数运算
由于编程语言提供的基本数值数据类型表示的数值范围有限,不能满足较大规模的高精度数值计算,因
此需要利用其他方法实现高精度数值的计算,于是产生了大数运算。大数运算主要有加、减、乘三种方
法。
中文名 大数运算 概 念 很大的数值的数进行一系列的运算 学 科 高等数学 应 用 空间力学
目录
1 简介2 原理
3 应用
▪ HDNOJ——1002 A + B Problem II
▪ HDNOJ 1002 代码
简介
大数运算,顾名思义,就是很大的数值的数进行一系列的运算。我们知道,在数学中,数值的大小是没有上限的,但是在计算机中,由于字长的限制,计算机所能表示
的范围是有限的,当我们对比较小的数进行运算时,如:1234+5678,这样的数值并没有超出计算机的表
示范围,所以可以运算。但是当我们在实际的应用中进行大量的数据处理时,会发现参与运算的数往往
超过计算机的基本数据类型的表示范围,比如说,在天文学上,如果一个星球距离我们为100万光年,那
么我们将其化简为公里,或者是米的时候,我们会发现这是一个很大的数。这样计算机将无法对其进行
直接计算。
可能我们认为实际应用中的大数也不过就是几百位而已,实际上,在某些领域里,甚至可能出现几百万
位的数据进行运算,这是我们很难想象的。如果没有计算机,那么计算效率可想而知。
既然在计算机中无法直接表示,那么大数到底如何进行运算呢,学习过数据结构的都知道线性表,将大
数拆分然后存储在线性表中,不失为一个很好的办法。
大数除法,可以类比人类手算,添位比较取商,中间结果与除数相减所得到的差参与下一轮运算,直到
结束。这里需要注意添位时,商有时需要补零,而且除法运算需要使用加、减、乘、比较运算。
原理
利用数组连续性,将大数每一位上的数字单独取出放入对应的数组格中,然后再对每一位做单独的加减
乘运算。形象的说,类似于小学学习加减乘所列的式子。
应用
HDNOJ——1002 A + B Problem II
Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 69615Accepted Submission(s): 12678
Problem Description
I have a very simple problem for you. Given two integers A and B, your job is to calculate
the Sum of A + B.
Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test
cases. Then T lines follow, each line consists of two positive integers, A and B. Notice
that the integers are very large, that means you should not process them by using 32-bit
integer. You may assume the length of each integer will not exceed 1000.
Output
For each test case, you should output two lines. The first line is "Case #:", # means the
number of the test case. The second line is the an equation "A + B = Sum", Sum means the
result of A + B. Note there are some spaces int the equation. Output a blank line between
two test cases.
Sample Input
2
1 2
112233445566778899 998877665544332211
Sample Output
Case 1:
1 + 2 = 3
Case 2:
112233445566778899 + 998877665544332211 = 1111111111111111110
Author
Ignatius.L
HDNOJ 1002 代码
#include <stdio.h>
#include <string.h>
int main()
{
char str1[1001],str2[1001];
int t,i,len_str1,len_str2,len_max,num=1,k;
scanf("%d",&t);
while(t--)
{
int a[1001]={0},b[1001]={0},c[1001]={0};
scanf("%s",str1);//输入第一个大数
len_str1=strlen(str1);//算出str1的长度,包括'\0'
for(i=0;i<=len_str1-1;++i)
a[i]=str1[len_str1-1-i]-'0';//将str1的值逆序赋值给a
scanf("%s",str2);//输入第二个大数
len_str2=strlen(str2);//算出str2的长度,包括'\0'
for(i=0;i<=len_str2-1;++i)
b[i]=str2[len_str2-1-i]-'0';//将str2的值逆序赋值给b
if(len_str1>len_str2)//判断谁的长度长,长度长的复制到len_max
len_max=len_str1;
else
len_max=len_str2;
k=0;
for(i=0;i<=len_max-1;++i)
{
c[i]=(a[i]+b[i]+k)%10;//取每位上两数相加的个位和
k=(a[i]+b[i]+k)/10;//将两数相加的十位数赋值到k
}
if(k!=0)//如果k还有剩余,说明数组c还有一位,而且不超过1
c[len_max]=1;
printf("Case%d:\n",num);//输出Case#:
num++;
printf("%s+%s=",str1,str2);//输出a+b=
if(c[len_max]==1)//输出最高位
printf("1");
for(i=len_max-1;i>=0;--i)//输出最高位以下的数
{
printf("%d",c[i]);
}
printf("\n");
if(t>=1)
printf("\n");
}
return0;
}
//上面代码是错的,WA,格式太差懒得改了,贴个对的。
#include <stdio.h>
#include <string.h>
int main()
{
char str1[1001],str2[1001];
int t,i,len_str1,len_str2,len_max,num=1,k;
scanf("%d",&t);
while(t--)
{
int a[1001]={0},b[1001]={0},c[1001]={0};
scanf("%s",str1);
len_str1=strlen(str1);
for(i=0;i<=len_str1-1;++i)
a[i]=str1[len_str1-1-i]-'0';
scanf("%s",str2);
len_str2=strlen(str2);
for(i=0;i<=len_str2-1;++i)
b[i]=str2[len_str2-1-i]-'0';
if(len_str1>len_str2)
len_max=len_str1;
else
len_max=len_str2;
k=0;
for(i=0;i<=len_max-1;++i)
{
c[i]=(a[i]+b[i]+k)%10;
k=(a[i]+b[i]+k)/10;
}
if(k!=0)
c[len_max]=1;
printf("Case%d:\n",num);
num++;
printf("%s+%s=",str1,str2);
if(c[len_max]==1)
printf("1");
for(i=len_max-1;i>=0;--i)
{
printf("%d",c[i]);
}
printf("\n");
//if(t>=1)
//printf("\n");
}
return 0;
}
========
大数相加
http://blog.youkuaiyun.com/hgy2011/article/details/8635251问题描述:实现A+B=C 其中A、B位数超过100位
算法思想:大数使用字符串存储,每一个单元存储操作数的每一位,之后执行位相加。
基本思路:字符串反转、字符变数字、位运算、反序输出
C语言代码:
#include<stdio.h>
#include<string.h>
#define Max 101
void print(char sum[]);
void bigNumAdd(char a[],char b[],char sum[]);
int main()
{
char a[Max];
char b[Max];
char sum[Max];
gets(a);
gets(b);
bigNumAdd(a,b,sum);
print(sum);
return 0;
}
void bigNumAdd(char a[],char b[],char sum[])
{
int i=0;
int c=0;//表示进位
//初始化,对以后位运算有很大帮助!
char m[Max]={0};
char n[Max]={0};
memset(sum,0,Max*sizeof(char)); //这里不能写成memset(sum,0,sizeof(sum));原因见注意事项1
//字符串反转且字符串变数字
int lenA=strlen(a);
int lenB=strlen(b);
for (i=0;i<lenA;i++)
{
m[i]=a[lenA-i-1]-'0';
}
for (i=0;i<lenB;i++)
{
n[i]=b[lenB-i-1]-'0';
}
//位运算
for (i=0;i<lenA||i<lenB;i++)
{
sum[i]=(m[i]+n[i]+c)%10+'0';//得到末位
c=(m[i]+n[i]+c)/10;//得到进位
}
}
void print(char sum[])
{
int i=0;
int j=0;
int len = strlen(sum);
for (i=len-1;sum[i]==0;i--); //找到第一个不为零的位置,方便输出
for (j=i;j>=0;j--)
{
printf("%c",sum[j]);
}
}
注意事项:
1、要注意sizeof的用法
char sum[100], sizeof(sum) =100 (表示整个字符串的大小)
char* sum 或 char sum[] (为函数参数), sizeof(sum)=4 (表示存储一个指针的单元大小)
主要的区别:sum在定义的时候意义不同
2、memset(sum,0,Max*sizeof(char)):
作用:一般是用于初始化或清空一个内存块,等价于循环
使用范围:百度说:在给char以外的数组赋值时,只能初始化为0或者-1,赋其他的值就要用循环
来实现。对字符数组可以赋任何字符
因为:在计算机里,0的二进制都是0,-1的二进制都是1。
3、在这里,对字符串进行初始化0操作很重要,它会影响到位操作和输出,要引起重视!
4、100位相加,和最大为101位,故申请最大为101
========
大数运算的算法
在数学运算的过程中 ,经常碰到这样的问题:参与运算的 数字很大或者对运算结果的精度要求很高。无
论何种计算机 语言 ,在描述数据类型时都有一定的精度和位数要求 ,比如说 16 位整型数 (int) 所能
表示的范围为 - 32768~32767 ,实数 (float)所能表示的精度为小数点后 8 位等 ,每种类型的数据都
有其精度和位数限制。超过 20 位有效数字的数值一般就无 法表示了。所以 ,在上述情况下 ,采用一般
的程序设计无法满 足要求 ,必须采用高精度的数学运算才能实现。如下例: 示例 1 :
Fibonacci Numbers
A Fibonacci sequence is calculated by adding the previous
two members of the sequence , with the first two members being
both 1. f (1) = 1 , f(2) = 1 , f (n > 2) = f (n - 1) + f(n - 2)
Your task is to take a number as input , and print that Fi2b onacci number.
Sample Input
100
Sample Output
354224848179261915075
Note: No generated Fibonacci number in excess of 1000 digits will be in the test data , i.
e. f (20) = 6765 has 4 digits.
这个示例的计算结果可能很大 ,以至于所有的数据类型 都无法表达。所以我们必须用高精度数学运算相
应的算法进 行求解。
1.大数存储的实现
作为实现大数存储最常见的一类方法是利用数组。将一 个有 n 位的大数存入数组 ,每个数组的一个元
素表示一位十 进制数 ,若是 n 没有超过普通 PC 机允许的定义范围 ,这种算 法是简单易行的。 如果
出现超大数 ,则可以采用万进制的方法加以存储 ,在 此就不多做介绍了。
2.大数计算的算法
这里仅对大数加法的算法做详细描述 ,剩下的运算给出 算法 ,具体程序实现过程留给读者思考。
2. 1 大数加法
看下面一个例子:
122345678902345
+ 34567890012
122380246792357
在上面的加法运算中 ,并没有考虑参与运算的数的位数 , 即使有小数也是一样。每次运算时只是利用加
法运算的规则 对参与运算的每一位进行运算 ,每次运算都是在 10 以内进 行 ,并加上了前面的进位。
通过这种运算就可以非常准确的 得到运算结果 ,并且可以不考虑位数和精度的问题。 考虑到计算机的
存储问题 ,如果我们采用数组来存储参 与运算的每个加数 ,则需要将上面参与运算的数看成字符 ,并
将原来的数翻转 ,即采用下面的运算方法:
543209876543221
+ 21009876543
753297642083221
我们看到运算结果与实际结果相反 ,因此只需要将结果 再翻转一次输出即可得到正确结果。这样做的好
处在于一旦 遇到低位向高位进位时 ,不会出现存储上的问题。因为最高 位存储在数组的最后一个元素
,其后的存储单元可用于存放 进位 ,同时运算是从数组的第一个元素开始的。 如何用 C语言来求解上面
的加法运算呢 ? 我们须首先定 义一个存储结构来存储每一个数。由于我们采用数组来存储 每一个数 ,
如果数的最大位数未知 ,则需采用指针方式定义 , 如果已知则可采用数组的方式来定义 ,在该示例中 ,
其最大位 数不超过 1000 位 ,因此可采用数组方式来定义 ,但由于每个 数的实际情况各不相同 ,因此
还必须定义一个变量来表示每 个数实际的位数。其存储结构用 C语言表示如下:
typedef struct fanum
{
char fnum[1001] ; / / 数 int len; / / 数的长度
}Fanum;
基于上面的存储结果及算法 ,我们可采用如下的 C 语言 程序实现两个多位数的加法运算 ,注意该数为
整数。
void strAdd(Fanum3sf1 ,Fanum3sf2)
{
int i ,len ,flag = 0 ;
Fanum sf3 ;
len = sf1 - > len > sf2 - > len ? sf1 - > len:sf2 - > len;
sf3. len = len; for(i = 0 ;i < len;i + + ){
sf3.fnum[i] = sf1 - > fnum[i] - ’0’ + sf2 - > fnum[i] - ’0 ’
+flag;
flag = sf3.fnum[i]/ 10 ;
sf3.fnum[i] = sf3.fnum[i] %10 +’0 ’;
} if (flag = = 1){
sf3.fnum[i] =’1 ’;
sf3. len + + ;
} for(i = 0 ;i < sf3. len;i + + ){
sf1 - >fnum[i] = sf2 - >fnum[i] ;
sf1 - > len = sf2 - > len;
sf2 - >fnum[i] = sf3.fnum[i] ;
sf2 - > len = sf3.len;
}
return;
}
注意此处用 sf1 存储加法运算的结果 ,sf2 用于存储运算 前 sf1 中存储的变量 ,主要是为了能够与上
面的示例更相吻 合。 有了上面的函数 ,要完成该题所规定的任务 ,只需要如下 的主程序便可实现。
int main()
{
FILE*in ,*out ;
Fanum f1 ,f2 ;
long num ,i ;
in =fopen(“ in. txt” , “r” ) ;
out =fopen(“out. txt” , “w” ) ;
while( fscanf (in ,“%d” , &num) ! = EOF)
{ f1. len = 1 ; f2. len = 1 ; for(i = 0 ;i < 1001 ;i + + )
{ f1.fnum[i] =’0 ’; f2.fnum[i] =’0 ’; }
f1.fnum[0] =’1 ’;
f2.fnum[0] =’1 ’;
while(num ! = 2)
{ strAdd( &f1 , &f2) ; num - - ; }
for(i =f2. len - 1 ;i > = 0 ;i - - )
fprintf (out ,“%d” ,f2.fnum[i] - ’0 ’) ;
fprintf (out ,“ \ n” ) ; }
fclose(in) ; fclose(out) ;
return 1 ;
}
该题输入数据存放在 in. txt 文件中 ,而输出结果存放在 out. txt 文件中。 大数加法运算实现算法
如下:
(1)将 A、 B 按位对齐;
(2)低位开始逐位相加;
(3)对结果做进位调整。
2. 2 大数减法
大数减法运算实现算法如下:
(1)将 A、 B 按位对齐;
(2)低位开始逐位相减;
(3)对结果做借位调整。
2. 3 大数乘法
大数乘法运算实现算法如下:
(1)引入 sum2 、 sum1 中间过渡量;
(2)在 n 的每一位上处理 m;
(3)通过每一层循环 ,实现乘法的加法化;
(4)对结果做进位调整。
2. 4 大数除法
大数除法运算实现算法如下:
(1)引入 al 来标识 a 的长度 , bl 来标识 b 的长度;
(2)测算 a 和 b 的长度;
(3)高位开始 ,对位做减法 ,并完成借位;
(4)高位开始逐位计算商; (5)整理商 , 产生余数。
2. 5 大数取模
在取模运算中用到了上面的除法运算 ,只需返回余数即 可。
3.结论
大数运算实际上都是建立在位运算的基础上的 ,实际上 就是对存储大数的数组里每一个数组项进行操作
。将大数翻 转过来存储是为了防止在计算过程中出现进位不好表示和溢 出的问题。这种处理也可以看
作是对字符串的处理 ,即把这 个数组里的每一位数字转化成字符进行处理。同时如果涉及 到小数 ,如
果是加法运算 ,可以把小数点前后的数据分开处 理;如果是乘法运算 ,可将其转换成整数运算之后 ,再
转换成 小数。
参考文献: [1]王永祥.超高精度超大数算法与程序设计[M].陕西:西安交通 大学出版社. 1990. 6. [2]
王昌锐.大数论[M]. 台北:徐氏基金会. 1970. [3]王金荣 等.大数模乘算法的分析与研究[J ]. 计算机
工程与应 用. 2004. 24. [4]Robert L. Kruse ,Alexander J. Ryba.“Data Structures And Pro2g
ram Design In C+ + ” . Higher Education Press Pearson Education. 5 , 2001.
}
========
大数运算(加减乘除,取模,乘方)
http://blog.youkuaiyun.com/agoago_2009/article/details/6862290#include "Big__CALC.h"
int main()
{
char str1[200]="9876543210987";
char str2[200]="1234567890";
char result[200]={0};
printf("str1 = %s\t%d\n",str1,strlen(str1)-1);
printf("str2 = %s\t%d\n",str2,strlen(str2)-1);
int ret = Compare(str1,str2);
if (ret==1)
{
printf("str1 > str2\n");
}
else if(ret==-1) printf("str1 < str2\n");
else printf("str1 = str2\n");
Add(str1,str2,result);
printf("str1 + str2 = %s\t%d\n",result,strlen(result)-1);
Sub(str1,str2,result);
printf("str1 - str2 = %s\t%d\n",result,strlen(result)-1);
Chen(str1,str2,result);
printf("str1 * str2 = %s\t%d\n",result,strlen(result)-1);
char div_result[200]={0};
Mod(str1,str2,result,div_result);
printf("str1 M str2 = %s\t%d\n",result,strlen(result)-1);
printf("str1 / str2 = %s\t%d\n",div_result,strlen(div_result)-1);
int num=10;
char str[200]="999";
ChenFang(str,num,result);
ThrowAway_0(str);
printf("%s ^ %d = %s\t%d\n",str,num,result,strlen(result)-1);
getchar();
return 1;
}
void Trans(char *str_num1, char *str_num2, char *tempbuf1, char *tempbuf2)
{
int len_num1=0;
int len_num2=0;
int i=0;
while(str_num1[i]!='\0')
{
len_num1++;
i++;
}
// printf("字符串1的长度: length1=%d\n",len_num1);
i=0;
while(str_num2[i]!='\0')
{
len_num2++;
i++;
}
// printf("字符串2的长度: length2=%d\n\n",len_num2);
tempbuf1[0]='0';
tempbuf2[0]='0';
//=======================================================================
if(len_num2>=len_num1) //补成相同长度
{
for(i=1;i<=(len_num2-len_num1);i++)
{
tempbuf1[i]='0';
}
for(i=len_num2-len_num1+1;i<=len_num2;i++)
{
tempbuf1[i]=str_num1[i-(len_num2-len_num1+1)];
}
for(i=1;i<=len_num2;i++)
{
tempbuf2[i]=str_num2[i-1];
}
}
//------------------------------------------
else if(len_num2<len_num1)
{
for(i=1;i<=(len_num1-len_num2);i++)
{
tempbuf2[i]='0';
}
for(i=len_num1-len_num2+1;i<=len_num1;i++)
{
tempbuf2[i]=str_num2[i-(len_num1-len_num2+1)];
}
for(i=1;i<=len_num1;i++)
{
tempbuf1[i]=str_num1[i-1];
}
}
/* printf("-------------------------------------------------------\n转换之后:\n");
printf("str1=: %s\n",tempbuf1);
printf("str2=: %s\n",tempbuf2);
//==========================================================================
int len=0;
i=0;
while(tempbuf1[i]!='\0')
{
len++;
i++;
}
*/
}
//=========================================================================================
===========
//extern "C" __declspec(dllexport)
void Chen(char *tempbuf1, char *tempbuf2 , char *result)
{
char buf1[200]={0};
char buf2[200]={0};
Trans(tempbuf1,tempbuf2,buf1,buf2);
strcpy(tempbuf1,buf1);
strcpy(tempbuf2,buf2);
int len=0;
int i=0;
int j=0;
int n=0;
int jinwei=0;
while(tempbuf1[i]!='\0') // 字符串长度
{
len++;
i++;
}
int temp[200]={0}; // 该数组用来存储各次方的系数 10为底
int max=2*len;
for(i=0;i<=max;i++)
{
if(i<len-1)
{
for(j=0;(j<=len-1)&&(j>=i+1-len)&&(j<=i);j++)
{
temp[i]+=((int)tempbuf1[len-1-j]-48 )*((int)tempbuf2[len-1-i+j]-48);
}
temp[i]+=jinwei;
if (temp[i]>=10) //&&temp[i]<100
{
jinwei = temp[i]/10;
temp[i] = temp[i]%10;
}
else jinwei=0;
}
else if (i>=len-1)
{
for(j=i-len+2;(j<=len-1)&&(j>=i+1-len)&&(j<=i);j++)
{
temp[i]+=((int)tempbuf1[len-1-j]-48 )*((int)tempbuf2[len-1-i+j]-48);
}
temp[i]+=jinwei;
if (temp[i]>=10) //&&temp[i]<100
{
jinwei = temp[i]/10;
temp[i] = temp[i]%10;
}
else jinwei=0;
}
}
i=max;
while(i>=0)
{
if(temp[i]!=0)
break;
else i--;
}
// printf("str1 * str2= ");
int num=i; // 科学计数法次数
/* for (j=num;j>=0;j--)
{
printf("%d",temp[j]);
}
printf("\t%d\n",num);
*/
//===========================================
memset(result,0,200);
for(i=num;i>=0;i--)
{
result[num-i]=(char)(temp[i]+48);
}
// printf("result = %s\t%d\n",result,strlen(result)-1);
}
//=====================================================================
//extern "C" __declspec(dllexport)
void ChenFang(char *tempbuf1, int num, char *result) // 大数乘方
{
static int count=0;
if (count==0)
{
char c[200]={'1',0,0};
memset(result,0,200);
Chen( tempbuf1 , c , result);
}
count++;
if(num==1)
{
return ;
}
else if(num>1)
{
Chen( tempbuf1 , result , result);
num--;
ChenFang(tempbuf1,num,result);
}
ThrowAway_0 (result);
}
//=================================================
//extern "C" __declspec(dllexport)
void Mod(char *tempbuf1, char *tempbuf2, char *result , char *div_result ) // 大数求
余
{
memset(result,0,200);
ThrowAway_0 (tempbuf1);
ThrowAway_0 (tempbuf2);
int max1 = strlen(tempbuf1);
int max2 = strlen(tempbuf2);
int temp=0;
int ret=1;
char div[200]={0};
int count=0;
char AfterSub[200]={0};
if(max1-max2>=0)
{
while(ret==1)
{
Sub (tempbuf1,tempbuf2,AfterSub); //减去之后在判断是否得到结果----即:
tempbuf1 < tempbuf2
memset(tempbuf1,0,200);
strcpy (tempbuf1,AfterSub);
ret=Compare(tempbuf1,tempbuf2);
ThrowAway_0 (tempbuf1);
ThrowAway_0 (tempbuf2);
count++;
if(count>=1000)
{
itoa(count,div,10);
Add(div_result,div,div_result);
count=0;
}
}
strcpy (result,tempbuf1);
ThrowAway_0 (result);
itoa(count,div,10);
Add(div_result,div,div_result);
}
else // if (Compare(tempbuf1,tempbuf2)==-1) // 后者大的话,mod 就是 tempbuf1
{
strcpy (result,tempbuf1);
ThrowAway_0 (result);
}
}
//========================================================
//extern "C" __declspec(dllexport)
void Add(char *tempbuf1, char *tempbuf2, char *result) // 大数相加 result = tempbuf1 +
tempbuf2
{
char buf1[200]={0};
char buf2[200]={0};
Trans(tempbuf1,tempbuf2,buf1,buf2);
strcpy(tempbuf1,buf1);
strcpy(tempbuf2,buf2);
int i=0;
int temp=0;
int jinwei=0;
int len=0;
while(tempbuf1[i]!='\0')
{
len++;
i++;
}
for(i=len-1;i>=0;i--)
{
temp=(int)(tempbuf1[i]+tempbuf2[i]+jinwei-96);
if(temp>=10)
{
temp=temp-10;
jinwei=1;
}
else jinwei=0;
result[i]=(char)(temp+48);
}
ThrowAway_0 (result);
}
//================================================
void ThrowAway_0 (char *tempbuf ) // 去除结果前面的 连续的无意义的 "0"
{
char buf[200]={0};
int n = strlen(tempbuf)-1;
int i=0;
while(i<n)
{
if (tempbuf[i]!='0')
{
break;
}
else
{
i++;
}
}
int Throw = i;
for (i=0;i<=n-Throw;i++)
{
buf[i]=tempbuf[i+Throw];
}
strcpy(tempbuf,buf);
}
//=======================================================
//extern "C" __declspec(dllexport)
void Sub(char *tempbuf1, char *tempbuf2, char *result) // 大数相减 result = tempbuf1 -
tempbuf2
{
ThrowAway_0 (tempbuf1);
ThrowAway_0 (tempbuf2);
memset(result,0,200);
char buf1[200]={0};
char buf2[200]={0};
Trans(tempbuf1,tempbuf2,buf1,buf2);
memset(tempbuf1,0,200);
memset(tempbuf2,0,200);
strcpy(tempbuf1,buf1);
strcpy(tempbuf2,buf2);
int i=0;
int temp=0;
int jiewei=0;
int len=0;
int ret=1;
while(tempbuf1[i]!='\0') // tempbuf1 和 tempbuf2 的长度相等
{
len++;
i++;
}
ret = Compare(tempbuf1,tempbuf2);
if(ret==1)
{
for(i=len-1;i>=0;i--)
{
temp = (int)tempbuf1[i] - (int)tempbuf2[i] - jiewei;
if (temp>=0)
{
result[i]=(char)(temp+48);
jiewei=0;
}
else if (temp<0)
{
result[i]=(char)(temp+10+48);
jiewei=1;
}
}
ThrowAway_0 (result);
}
else if(ret==0)
{
memset(result,0,200);
result[0]='0';
}
else if(ret==-1)
{
for(i=len-1;i>=0;i--)
{
temp = (int)tempbuf2[i] - (int)tempbuf1[i] - jiewei;
if (temp>=0)
{
result[i]=(char)(temp+48);
jiewei=0;
}
else if (temp<0)
{
result[i]=(char)(temp+10+48);
jiewei=1;
}
}
ThrowAway_0 (result);
memset(buf1,0,200);
sprintf(buf1,"-%s",result);
strcpy(result,buf1);
}
}
//======================================================================
//===================================================================================
int Compare(char *tempbuf1,char *tempbuf2)
{
ThrowAway_0 (tempbuf1);
ThrowAway_0 (tempbuf2);
char buf1[200]={0};
char buf2[200]={0};
Trans(tempbuf1,tempbuf2,buf1,buf2);
memset(tempbuf1,0,200);
memset(tempbuf2,0,200);
strcpy(tempbuf1,buf1);
strcpy(tempbuf2,buf2);
int ret=1;
int count=0;
while(count<200)
{
int m=(int)tempbuf1[count]-48;
int n=(int)tempbuf2[count]-48;
if(m==n)
{
count++;
ret=0;
}
else if(m>n)
{
// printf("tempbuf1>tempbuf2\n");
ret=1;
break;
}
else if(m<n)
{
// printf("tempbuf1<tempbuf2\n");
ret=-1;
break;
}
}
return ret;
}
2.头文件
[cpp] view plain copy
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//extern "C" __declspec(dllexport)
void Add (char *tempbuf1, char *tempbuf2, char *result); // 大数相加 result = tempbuf1 +
tempbuf2
//extern "C" __declspec(dllexport)
void Sub(char *tempbuf1, char *tempbuf2, char *result); // 大数相减 result = tempbuf1 -
tempbuf2 (默认前者大)
int Compare(char *tempbuf1,char *tempbuf2);
//extern "C" __declspec(dllexport)
void Chen (char *tempbuf1, char *tempbuf2, char *result); // 大数相乘 result = tempbuf1 *
tempbuf2
void Trans (char *str_num1, char *str_num2, char *tempbuf1, char *tempbuf2); // 大数转化
为等长,且最前面添加 “0”
//extern "C" __declspec(dllexport) // 大数除法
div_result = tempbuf1 / tempbuf2
void Mod(char *tempbuf1, char *tempbuf2, char *result , char *div_result ); // 大数求
余 result = tempbuf1 % tempbuf2
//extern "C" __declspec(dllexport)
void ChenFang (char *tempbuf1, int num, char *result); // 大数乘方 result =
tempbuf1 ^ num
void ThrowAway_0 (char *tempbuf ); // 去除结果前面的 连续的无意义的 "0"
========