C语言大数四则运算

话不多说,直接上代码

参考了一下已有思路,将缺失的函数填补,以及一些bug更改了一些

资料来源:C语言实现大数四则运算 - 鱼儿游上天 - 博客园

如有侵权,请联系删除~

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
const int LEN=99999; //自定义计算最大值长度 ,默认99999 

typedef struct num{
    int len;   //数值长度 
    char symbol; //数字正负形 
    int number[LEN]; //数组 
}NUM,*SNUM;

SNUM expToNum(char exp[]);//将输入字符串转换为对应结构体 
void reverse(int a[],int len);//数组逆序
int compareAbs(SNUM left,SNUM right);//比较两数绝对值大小 
SNUM anti_add(SNUM left,SNUM right);//元加法
SNUM anti_sub(SNUM left,SNUM right);//元减法 
SNUM add(SNUM left,SNUM right);  //加法 
SNUM sub(SNUM left,SNUM right);  //减法
SNUM multiply(SNUM left,SNUM right); //乘法 
SNUM divide(SNUM left,SNUM right); //除法 
SNUM mod(SNUM left,SNUM right);//求模运算

//实现正数或负数的加法
SNUM add(SNUM left,SNUM right){
    SNUM temp;
    if(left->symbol==right->symbol){
        temp = anti_add(left,right);
    }else{
        if(compareAbs(left,right)>=0){
               temp = anti_sub(left,right);

        }else{
             temp = anti_sub(right,left);
        }
    }
    return temp;
}

SNUM mod(SNUM left,SNUM right)
{
    SNUM mod = (struct num*)malloc(sizeof(struct num));
    for(int i=0;i<LEN;i++){
        mod->number[i]=0;   
    }
    mod=sub(left,multiply(right,divide(left,right)));
    return mod;
}

SNUM divide(SNUM left,SNUM right) 
{
    SNUM div = (struct num*)malloc(sizeof(struct num));
    SNUM temp= (struct num*)malloc(sizeof(struct num));
    SNUM addition=(struct num*)malloc(sizeof(struct num));
    int i,j,a,b,len;
    for(i=0;i<LEN;i++){
        div->number[i]=0;   
        temp->number[i]=0;
    }
    if(left->symbol==right->symbol){
        div->symbol='+';
    }else{
        div->symbol='-';
    }
    len=left->len-right->len+1;
    div->len=len;    
    for(a=len-1;a>=0;a--)
    {
        for(b=9;b>=0;b--)
        {
            
            div->number[a]=b;
            temp=multiply(right,div);
            if(compareAbs(temp,left)!=1)
                break;
        }
        temp=sub(left,multiply(right,div));
        if(compareAbs(right,temp)==1)
            break;
    }
    //舍去多余0位
    for(i=len-1;i>=0;i--)
    {
        if(div->number[i]==0)
        {
            len--;
        }
        else
        {
            break;
        }
    }
    if(len<=0)
    {
        len=1;
    }
    div->len=len;
    addition->len=1;
    addition->symbol='-';
    addition->number[0]=1;
    if(div->symbol=='-'&&sub(left,temp)->number[0]==0)
        div=anti_add(div,addition);    
    return div;
}

SNUM multiply(SNUM left,SNUM right){
    //left作为被乘数,right作为乘数
    SNUM mul = (struct num*)malloc(sizeof(struct num));
    int i,j;
    for(i=0;i<LEN;i++){
        mul->number[i]=0;
    }
    if(left->symbol==right->symbol){
        mul->symbol='+';
    }else{
        mul->symbol='-';
    }
    for(i=0;i<right->len;i++){
        for(j=0;j<left->len;j++){
            mul->number[i+j]+=left->number[j]*right->number[i];
        }
    }
//    //进位化简
     int len = left->len+right->len-1; //长度

//
     for(i=0;i<len;i++){
            mul->number[i+1]+=mul->number[i]/10;
            mul->number[i]%=10;

            if(i==len-1){
                if(mul->number[i+1]!=0){ //还存在高位
                    len++;
                }else{ //进位完毕,退出
                    break;
                }
            }
     }
//     //舍去多余0位
    for(i=len-1;i>=0;i--){
         if(mul->number[i]==0){
             len--;
         }else{
             break;
         }
     }
     if(len==0){
         len=1;
     }

     mul->len=len;

    //free(left);
    //free(right);
    return mul;
}

//减一个数等于加上一个数的相反数
SNUM sub(SNUM left,SNUM right){
    SNUM temp=right;
    temp->symbol=(temp->symbol=='+'?'-':'+');
    return add(left,temp);
}

//比较两数绝对值大小
int compareAbs(SNUM left,SNUM right){
    if(left->len>right->len){   //left的位数更多
        return 1;
    }else if(left->len<right->len){ //right的位数更多
        return -1;
    }else{
        int i=left->len-1;
        while(i>=0){   //从高位开始比较
            if(left->number[i]>right->number[i]){
                return 1;
            }
            if(left->number[i]<right->number[i]){
                return -1;
            }
            i--;
        }
        return 0; //两者绝对值相等
    }
}


SNUM expToNum(char exp[]){

    SNUM temp=(struct num*)malloc(sizeof(struct num));

    int locan=0;
    //确定正负号
    if(exp[0]=='+'||exp[0]=='-'){
          temp->symbol=exp[0];
          locan++;
    }else{
          temp->symbol='+';
    }

    //输入到数组
    int count=0;
    while(exp[locan]!='\0'){
        temp->number[count]=exp[locan]-'0';
        locan++;
        count++;
    }

    int i=count;
    for(i=count;i<LEN-1;i++){
        temp->number[i]=0;
    }

    temp->len=count;


    //数组逆序从个位开始计算
    reverse(temp->number,temp->len);

    return temp;
}

//数组逆序
void reverse(int a[],int len){
    int i,temp;
    for(i=0;i<len/2;i++){
        temp = a[i];
        a[i] = a[len-1-i];
        a[len-1-i] = temp;
    }
}

//元加法,假设left和right都为正数或0
SNUM anti_add(SNUM left,SNUM right){
    int i=0;
    SNUM temp=(struct num*)malloc(sizeof(struct num));
    temp->symbol=left->symbol;
    temp->len=left->len;
    for(int j=0;j<temp->len;j++)
        temp->number[j]=left->number[j];    
    while(i<left->len||i<right->len){
        int sum=0;
        sum=temp->number[i]+right->number[i];
        if(sum>=10){
            temp->number[i]=sum%10;
            temp->number[i+1]+=sum/10;   //进位
        }else{
            temp->number[i]=sum;   //不进位
        }
        i++;
    }

    if(temp->number[i]!=0){
        i+=1;
    }

    temp->len=i;
    return temp;
}

//元减法,假设left>=right,left和right均为正数或0
SNUM anti_sub(SNUM left,SNUM right){
    int i=0;
    int count=0;
    SNUM temp1=(struct num*)malloc(sizeof(struct num));
    temp1->symbol=left->symbol;
    temp1->len=left->len;
    for(int j=0;j<temp1->len;j++)
        temp1->number[j]=left->number[j];    
     while(i<left->len){
         int temp =temp1->number[i]-right->number[i];
         if(temp<0){
              temp1->number[i+1]-=1;
              temp1->number[i]=temp+10; //退位
         }else{
              temp1->number[i]=temp;
         }
             count+=1;
         i++;
     }
     //舍掉多余的0
     for(i=count-1;i>=0;i--){
         if(temp1->number[i]==0){
             count--;
         }else{
             break;
         }
     }

     if(count==0){
         count++;
     }
     temp1->len=count;
     return temp1;

}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值