话不多说,直接上代码
参考了一下已有思路,将缺失的函数填补,以及一些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;
}