大整数四则运算
数据结构课的作业,实现大整数的四则运算。
一、效果图
二、头函数
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct BigNum{
int num[1000];
int carry[1000];
int length;
}BigNum;
void AddNum(BigNum &Na,BigNum &Nb,BigNum &Nc); //加法
void SubstractNum(BigNum &Na,BigNum &Nb,BigNum &Nc); //减法
void MultiplyNum(BigNum &Na,BigNum &Nb,BigNum &Nc); //乘法
void DivideNum(BigNum &Na,BigNum &Nb,BigNum &Nc); //除法
void Init(BigNum &N); //初始化
void IntToChar(BigNum &N,char c[]); //整型变字符型,最终输出时用到
int Compare(BigNum &Na,BigNum &Nb); //比较大小
void NegToPos(BigNum &N); //负数改为正数
void PosToNeg(BigNum &N);//正数改为负数
三、测试程序
#include"BigNum.h"
int main(){
BigNum Na,Nb,Nc;
char a[1000],b[1000],c[1000];
int i;
int op;
while(1){
printf("请输入需要执行的操作:\n");
printf("1.相加\n");
printf("2.相减\n");
printf("3.相乘\n");
printf("4.相除\n");
printf("5.比较大小\n");
printf("6.退出\n");
scanf("%d",&op);
if(op==6){
printf("再见!\n");
exit(0);
}
printf("请分别输入两个大整数Na和Nb:\n");
scanf("%s",a);
scanf("%s",b);
for(i=0;a[i]!='\0';i++){
Na.num[i]=a[i]-'0';
}
Na.length=i;
for(i=0;b[i]!='\0';i++){
Nb.num[i]=b[i]-'0';
}
Nb.length=i;
switch(op){
case 1:{
AddNum(Na,Nb,Nc);
IntToChar(Nc,c);
printf("%s\n",c);
break;
}
case 2:{
SubstractNum(Na,Nb,Nc);
IntToChar(Nc,c);
printf("%s\n",c);
break;
}
case 3:{
MultiplyNum(Na,Nb,Nc);
IntToChar(Nc,c);
printf("%s\n",c);
break;
}
case 4:{
DivideNum(Na,Nb,Nc);
IntToChar(Nc,c);
printf("%s\n",c);
break;
}
case 5:{
int ans=Compare(Na,Nb);
if(ans==1) printf("Na大\n");
if(ans==0) printf("Na和Nb一样大\n");
if(ans==-1) printf("Nb大\n");
break;
}
case 6:{
printf("再见!\n");
exit(0);
}
}
}
return 0;
}
四、主函数
#include"BigNum.h"
void AddNum(BigNum &Na,BigNum &Nb,BigNum &Nc){ //加法
int ia=0,ib=0,ic=0;
if(Na.num[0]!=-3&&Nb.num[0]!=-3){ //Na、Nb都为正数
if(Compare(Na,Nb)==1||Compare(Na,Nb)==0){
Nc.length=Na.length+1; //Nc表长+1(考虑最长情况)
Init(Nc);
for(ia=Na.length-1,ib=Nb.length-1,ic=Nc.length-1;ib>=0;ia--,ib--,ic--){
if(Na.num[ia]+Nb.num[ib]+Nc.carry[ic]>=10){
Nc.carry[ic-1]=1;
Nc.num[ic]=(Na.num[ia]+Nb.num[ib]+Nc.carry[ic])%10;
}
else{
Nc.carry[ic-1]=0;
Nc.num[ic]=Na.num[ia]+Nb.num[ib]+Nc.carry[ic];
}
}
for(;ia>=0;ia--,ic--){ //若Na有剩余数字,则将剩余数字加到Nc的前面
if(Na.num[ia]+Nc.carry[ic]>=10){
Nc.carry[ic-1]=1;
Nc.num[ic]=(Na.num[ia]+Nc.carry[ic])%10;
}
else{
Nc.carry[ic-1]=0;
Nc.num[ic]=Na.num[ia]+Nc.carry[ic];
}
}
if(Nc.carry[0]==0) { //如果Nc第一位为0,则表长-1,元素左移一位
Nc.length--;
for(ic=0;ic<Nc.length;ic++){
Nc.num[ic]=Nc.num[ic+1];
}
}
else if(Nc.carry[0]==1){ //Nc第一位进位为1
Nc.num[0]=Nc.carry[1];
}
}
else if (Compare(Na,Nb)==-1){
Nc.length=Nb.length+1;
Init(Nc);
for(ia=Na.length-1,ib=Nb.length-1,ic=Nc.length-1;ia>=0;ia--,ib--,ic--){
if(Na.num[ia]+Nb.num[ib]+Nc.carry[ic]>=10){
Nc.carry[ic-1]=1;
Nc.num[ic]=(Na.num[ia]+Nb.num[ib]+Nc.carry[ic])%10;
}
else {
Nc.carry[ic-1]=0;
Nc.num[ic]=Na.num[ia]+Nb.num[ib]+Nc.carry[ic];
}
}
for(;ib>=0;ib--,ic--){
if(Nb.num[ib]+Nc.carry[ic]>=10){
Nc.carry[ic-1]=1;
Nc.num[ic]=(Nb.num[ib]+Nc.carry[ic])%10;
}
else{
Nc.carry[ic-1]=0;
Nc.num[ic]=Nb.num[ib]+Nc.carry[ic];
}
}
if(Nc.carry[0]==0) {
Nc.length--;
for(ic=0;ic<Nc.length;ic++){
Nc.num[ic]=Nc.num[ic+1];
}
}
else if(Nc.carry[0]==1){
Nc.num[0]=Nc.carry[1];
}
}
}
else if(Na.num[0]==-3&&Nb.num[0]==-3){ //Na、Nb同时为负
NegToPos(Na);NegToPos(Nb);
AddNum(Na,Nb,Nc);
PosToNeg(Nc);
}
else if(Na.num[0]!=-3&&Nb.num[0]==-3){ //Na正,Nb负
NegToPos(Nb);
if(Compare(Na,Nb)==1||Compare(Na,Nb)==0){
SubstractNum(Na,Nb,Nc);
}
else if(Compare(Na,Nb)==-1){
SubstractNum(Nb,Na,Nc);
PosToNeg(Nc);
}
}
else if(Na.num[0]==-3&&Nb.num[0]!=-3){ //Na负,Nb正
NegToPos(Na);
if(Compare(Na,Nb)==1||Compare(Na,Nb)==0){
SubstractNum(Na,Nb,Nc);
PosToNeg(Nc);
}
else if(Compare(Na,Nb)==-1){
SubstractNum(Nb,Na,Nc);
}
}
}
void SubstractNum(BigNum &Na,BigNum &Nb,BigNum &Nc){ //减法
int ia=0,ib=0,ic=0;
int flag=0;
int Len_c;
if(Na.num[0]!=-3&&Nb.num[0]!=-3){
if(Compare(Na,Nb)==1||Compare(Na,Nb)==0){
Nc.length=Na.length;
Init(Nc);
for(ia=Na.length-1,ib=Nb.length-1,ic=Nc.length-1;ib>=0;ia--,ib--,ic--){
if(Na.num[ia]-Nb.num[ib]+Nc.carry[ic]<0){
Nc.carry[ic-1]=-1;
Nc.num[ic]=(Na.num[ia]+10-Nb.num[ib]+Nc.carry[ic])%10;
}
else{
Nc.carry[ic-1]=0;
Nc.num[ic]=Na.num[ia]-Nb.num[ib]+Nc.carry[ic];
}
}
for(;ia>=0;ia--,ic--){
if(Na.num[ia]+Nc.carry[ic]<0){
Nc.carry[ic-1]=-1;
Nc.num[ic]=(Na.num[ia]+10+Nc.carry[ic])%10;
}
else{
Nc.carry[ic-1]=0;
Nc.num[ic]=Na.num[ia]+Nc.carry[ic];
}
}
Len_c=Nc.length;
for(ic=0;Nc.num[ic]==0&&flag<Len_c-1;ic=0){ //将Nc首位为0的元素全部删除,直至首位为非0元素
Nc.length--;
flag++;
for(int ic_=0;ic_<Nc.length;ic_++){
Nc.num[ic_]=Nc.num[ic_+1];
}
}
}
else if(Compare(Na,Nb)==-1){
Nc.length=Nb.length;
SubstractNum(Nb,Na,Nc);
PosToNeg(Nc);
}
}
else if(Na.num[0]==-3&&Nb.num[0]==-3){
if(Compare(Na,Nb)==1||Compare(Na,Nb)==0){
NegToPos(Na);NegToPos(Nb);
Nc.length=Nb.length;
Init(Nc);
SubstractNum(Nb,Na,Nc);
}
else if(Compare(Na,Nb)==-1){
NegToPos(Na);NegToPos(Nb);
Nc.length=Na.length;
Init(Nc);
SubstractNum(Nb,Na,Nc);
}
}
else if(Na.num[0]!=-3&&Nb.num[0]==-3){
NegToPos(Nb);
Nc.length=Na.length>Nb.length ? Na.length : Nb.length;
Init(Nc);
AddNum(Na,Nb,Nc);
}
else if(Na.num[0]==-3&&Nb.num[0]!=-3){
NegToPos(Na);
Nc.length=Na.length>Nb.length ? Na.length : Nb.length;
Init(Nc);
AddNum(Na,Nb,Nc);
PosToNeg(Nc);
}
}
void MultiplyNum(BigNum &Na,BigNum &Nb,BigNum &Nc){ //乘法
//两次循环,外循环从Nb的个位开始向高位循环,内循环从Na的个位开始向高位循环,依次做乘法,保留进位。
int ia=0,ib=0,ic=0;
if(Na.num[0]==0&&Na.length==1||Nb.num[0]==0&&Nb.length==1){
Init(Nc);
Nc.length=1;
Nc.num[0]=0;
}
else{
if(Na.num[0]!=-3&&Nb.num[0]!=-3){
if(Compare(Na,Nb)==1||Compare(Na,Nb)==0){
Nc.length=Na.length*2;
Init(Nc);
int cnt=1; //cnt为外循环执行的次数
for(ib=Nb.length-1,ic=Nc.length-cnt;ib>=0;ib--,ic=Nc.length-cnt){
Nc.carry[ic]=0;
for(ia=Na.length-1;ia>=0;ia--,ic--){
if(Na.num[ia]*Nb.num[ib]+Nc.carry[ic]>=10){
Nc.carry[ic-1]=(Na.num[ia]*Nb.num[ib]+Nc.carry[ic])/10;
Nc.num[ic]+=(Na.num[ia]*Nb.num[ib]+Nc.carry[ic])%10;
}
else {
Nc.carry[ic-1]=0;
Nc.num[ic]+=Na.num[ia]*Nb.num[ib]+Nc.carry[ic];
}
if(Nc.num[ic]>=10) {
Nc.num[ic-1] += Nc.num[ic]/10;
Nc.num[ic] = Nc.num[ic]%10;
}
}
Nc.num[ic]+=Nc.carry[ic];
cnt++;
}
}
else if(Compare(Na,Nb)==-1){
MultiplyNum(Nb,Na,Nc);
}
}
else if(Na.num[0]==-3&&Nb.num[0]==-3){
NegToPos(Na);NegToPos(Nb);
MultiplyNum(Na,Nb,Nc);
}
else if(Na.num[0]!=-3&&Nb.num[0]==-3){
NegToPos(Nb);
MultiplyNum(Na,Nb,Nc);
PosToNeg(Nc);
}
else if(Na.num[0]==-3&&Nb.num[0]!=-3){
NegToPos(Na);
MultiplyNum(Na,Nb,Nc);
PosToNeg(Nc);
}
for(ic=0;Nc.num[ic]==0;ic=0){
Nc.length--;
for(int ic_=0;ic_<Nc.length;ic_++){
Nc.num[ic_]=Nc.num[ic_+1];
}
}
}
}
void DivideNum(BigNum &Na,BigNum &Nb,BigNum &Nc){ //除法
int ia=0,ib=0,ic=0;
int i,i_;
int quotient;//商
BigNum dividend,divisor; //被除数 ,除数
BigNum current,Nd,answer;
Init(divisor);Init(dividend);
Init(current);Init(Nd);
dividend=Na; divisor=Nb;
Nd.length=1;
if(Na.num[0]!=-3&&Nb.num[0]!=-3){
if(Compare(Na,Nb)==1||Compare(Na,Nb)==0){
Nc.length=Na.length;
current.length=Nb.length;
for(ia=0;ia<Nb.length;ia++){
current.num[ia] = Na.num[ia];
}
if(Compare(current,Nb)==1||Compare(current,Nb)==0){
Init(Nc);
Nc.length=Na.length-Nb.length+1;
dividend.length=Nb.length;
while(ic!=Nc.length){
for(quotient=1;quotient<=10;quotient++){
Nd.num[0]=quotient;
MultiplyNum(Nd,Nb,answer);
if(Compare(answer,current)==1){
quotient--; break;
}
else if(Compare(answer,current)==0) break;
}
Nc.num[ic++]=quotient;
Nd.num[0]=quotient;
MultiplyNum(Nd,divisor,answer);
SubstractNum(current,answer,dividend);
if(dividend.length==Nb.length&&Nb.length!=1) dividend.length=Nb.length+1;
else dividend.length=Nb.length;
int flag=0;
if(dividend.num[0]==0&÷nd.length==2) flag=1;
for(i=0;dividend.num[i]==0&&ic!=Nc.length;i=0){ //将dividend首位为0的元素全部删除,直至首位为非0元素
for(int i_=0;i_<dividend.length;i_++){
dividend.num[i_]=dividend.num[i_+1];
}
}
if(flag==1) dividend.length--;
dividend.num[dividend.length-1]=Na.num[ia++];
current=dividend;
}
}
else if(Compare(current,Nb)==-1){
current.length=Nb.length+1;
for(ia=0;ia<=Nb.length;ia++){
current.num[ia] = Na.num[ia];
}
Init(Nc);
Nc.length=Na.length-Nb.length;
dividend.length=Nb.length+1;
while(ic!=Nc.length){
for(quotient=1;quotient<=10;quotient++){
Nd.num[0]=quotient;
MultiplyNum(Nd,Nb,answer);
if(Compare(answer,current)==1){
quotient--; break;
}
else if(Compare(answer,current)==0) break;
}
Nc.num[ic++]=quotient;
Nd.num[0]=quotient;
MultiplyNum(Nd,divisor,answer);
SubstractNum(current,answer,dividend);
if(dividend.num[0]!=0) dividend.length=Nb.length+1;
else dividend.length=Nb.length;
dividend.num[dividend.length-1]=Na.num[ia++];
current=dividend;
}
}
}
}
else if(Na.num[0]==-3&&Nb.num[0]==-3){
NegToPos(Na);NegToPos(Nb);
DivideNum(Na,Nb,Nc);
}
else if(Na.num[0]!=-3&&Nb.num[0]==-3){
NegToPos(Nb);
DivideNum(Na,Nb,Nc);
PosToNeg(Nc);
}
else if(Na.num[0]==-3&&Nb.num[0]!=-3){
NegToPos(Na);
DivideNum(Na,Nb,Nc);
PosToNeg(Nc);
}
}
void Init(BigNum &N){ //初始化
int i;
for(i=0;i<N.length;i++){
N.num[i]=0;
N.carry[i]=0;
}
}
void IntToChar(BigNum &N,char c[]){ //整型变字符型 ,最终输出时用到
int i;
for(i=0;i<N.length;i++){
c[i]=N.num[i]+'0';
}
c[i]='\0';
}
int Compare(BigNum &Na,BigNum &Nb){ //比较大小
if(Na.num[0]!=-3&&Nb.num[0]==-3) return 1; //Na正,Nb负,则Na大
else if(Na.num[0]==-3&&Nb.num[0]!=-3) return -1; //Na负,Nb正,则Nb大
else if(Na.num[0]==-3&&Nb.num[0]==-3){ //Na、Nb同为负
if(Na.length>Nb.length) return -1;
else if(Na.length<Nb.length) return 1;
else if(Na.length==Nb.length){
for(int i=1;i<Na.length;i++){
if(Na.num[i]<Nb.num[i]) return 1;
else if(Na.num[i]>Nb.num[i]) return -1;
}
return 0;
}
}
else if(Na.num[0]!=-3&&Nb.num[0]!=-3){ //Na、Nb同为正
if(Na.length>Nb.length) return 1;
else if(Na.length<Nb.length) return -1;
else if(Na.length==Nb.length){
for(int i=0;i<Na.length;i++){
if(Na.num[i]<Nb.num[i]) return -1;
else if(Na.num[i]>Nb.num[i]) return 1;
}
return 0;
}
}
}
void NegToPos(BigNum &N){ //负数变正数
int i;
N.length--;
for(i=0;i<N.length;i++){
N.num[i]=N.num[i+1];
}
}
void PosToNeg(BigNum &N){ //正数变负数
int i;
N.length++;
for(i=N.length-1;i>0;i--){
N.num[i]=N.num[i-1];
}
N.num[0]=-3;
}