大整数,超过c++ longlong范围的一些数字,可以使用Java自带的大数类进行运算,或者使用字符串进行模拟加减法,这里说一下使用c++字符串进行模拟加减法。
加法
对于加法,首先使用字符串将两个大数读进来,这里注意一下,由于最高位是第一个读进来的数字,所以最高位是首位。如果使用字符数组的话,建议逆置一下。链表的话就没有必要了。然后我们就需要将两个大数进行逐位相加,本人不建议在逐位相加时处理进位,最后处理进位,相加完之后,在从末尾开始处理进位,对于大于10的数字,想前一位进一。(这里简单用数组演示一下):
然后需要从最低未开始向高位处理进位,按照逢十进一的原则处理进位即可,这里注意下,有可能将最高位处理为两位数,这时又需要进位了,如果是仅仅需要输出大整数计算结果,那么最高位不进位也没有关系,因为进位只是把最高位的两位数拆分成了两个数字。如果后续还有其他运算,那么建议进位。
减法
对于减法来说,读入过程和加法相同,但需要注意的时,减法需要长度长的数字去间长度短的数字,否则会造成错误(自己最初被这个问题坑了半天),然后就需要逐位相减,最后统一处理借位即可,和加法大同小异,这里不再论述。
下面看一下代码(链表版)(由于课本的要求 ,需要按照每四位一个逗号进行输入如输出):
#include<bits/stdc++.h>
using namespace std;
struct node{
int date;
node *next,*pre;
int flag;
}*head1,*head2;
void add(int flag){
node *l1=head1,*l2=head2,*p,*q;
while(l2!=NULL){ //各位相加
l1->date+=l2->date;
l1=l1->next;
l2=l2->next;
}
l1=head1;
while(l1->next!=NULL){ //处理进位
if(l1->date>=10){
l1->next->date+=l1->date/10;
l1->date%=10;
}
l1=l1->next;
}
if(l1->date>=10){ //最高位进位分析
p=(node *)malloc(sizeof(node));
p->date=l1->date/10;
l1->date%=10;
l1->next=p;
p->next=NULL;
}
int count=0; //逗号添加
p=head1;
while(p){
if(count%4==0&&count>=4) p->flag=1;
p=p->next;
count++;
}
q=head1; //链表逆置
p=head1->next;
while(p){
head1->next=p->next;
p->next=q;
q=p;
p=head1->next;
}
head1->next=NULL;
if(flag==-1) cout<<"-"; //正负判断
while(q){ //输出
cout<<q->date;
if(q->flag==1) cout<<',';
q=q->next;
}
}
void substr(){
node *l1=head1,*l2=head2,*p,*q,*newhead;
while(l2!=NULL){ //逐位相减
l1->date-=l2->date;
l1=l1->next;
l2=l2->next;
}
l1=head1; //处理借位
while(l1->next!=NULL){
if(l1->date<0){
l1->date+=10;
l1->next->date-=1;
}
l1=l1->next;
}
int count=0; //逗号添加
p=head1;
while(p){
if(count%4==0&&count>0) p->flag=1;
count++;
p=p->next;
}
q=head1; //链表逆置
p=head1->next;
while(p){
head1->next=p->next;
p->next=q;
q=p;
p=head1->next;
}
head1->next=NULL;
int book=0;
while(q){ //输出
if(q->date!=0||book){
book=1;
cout<<q->date;
if(q->flag==1) cout<<",";
}
q=q->next;
}
}
int main(){
cout<<"please input two integer:"<<endl;
string str1,str2;
cin>>str1>>str2;
if((str1[0]=='-'&&str2[0]=='-')||(str1[0]>='0'&&str1[0]<='9'&&str2[0]>='0'&&str2[0]<='9')){ //符号相同
int flag=1;
if(str1[0]=='-') flag=-1;
node *p,*pre;
int len1=str1.length();
int len2=str2.length();
for(int q=len1-1;q>(flag==-1?0:-1);q--){
if(str1[q]==',') continue;
p=(node *)malloc(sizeof(node));
p->flag=0;
p->date=str1[q]-'0';
if(q==len1-1) { len1>len2?head1=p:head2=p; }
else { pre->next=p; }
pre=p;
}
p->next=NULL;
for(int q=len2-1;q>(flag==-1?0:-1);q--){
if(str2[q]==',') continue;
p=(node *)malloc(sizeof(node));
p->flag=0;
p->date=str2[q]-'0';
if(q==len2-1) { len2>=len1?head1=p:head2=p; }
else { pre->next=p; }
pre=p;
}
p->next=NULL;
add(flag);
}
else{ //符号不同
node *p,*pre,*q;
int len1=str1.length();
int len2=str2.length();
int u=0;
if(str1[0]=='-'){
for(int q=len1-1;q>0;q--){
if(str1[q]==',') continue;
p=(node *)malloc(sizeof(node));
if(q==len1-1) { head1=p; }
else { pre->next=p; }
p->flag=0;
p->date=str1[q]-'0';
pre=p;
}
p->next=0;
for(int q=len2-1;q>=0;q--){
if(str2[q]==',') continue;
p=(node *)malloc(sizeof(node));
if(q==len2-1) { head2=p; }
else { pre->next=p; }
p->flag=0;
p->date=str2[q]-'0';
pre=p;
}
p->next=0;
if(strcmp(&str1[1],&str2[0])==0) cout<<"0";
else{
if(len1-1>len2){
cout<<"-";
substr();
}
else if(len1-1==len2){
if(strcmp(&str1[1],&str2[0])>0){
cout<<"-";
}
substr();
}
else {
p=head1;head1=head2;head2=p;
substr();
}
}
}
else{
for(int q=len1-1;q>=0;q--){
if(str1[q]==',') continue;
p=(node *)malloc(sizeof(node));
if(q==len1-1) { head1=p; }
else { pre->next=p; }
p->flag=0;
p->date=str1[q]-'0';
pre=p;
}
p->next=0;
for(int q=len2-1;q>0;q--){
if(str2[q]==',') continue;
p=(node *)malloc(sizeof(node));
if(q==len2-1) { head2=p; }
else { pre->next=p; }
p->flag=0;
p->date=str2[q]-'0';
pre=p;
}
p->next=0;
if(strcmp(&str1[0],&str2[1])==0) cout<<"0";
else{
if(len2-1>len1){
p=head1;head1=head2;head2=p;
cout<<"-";
substr();
}
else if(len2-1==len1){
if(strcmp(&str1[0],&str2[1])>0){
substr();
}
else {
p=head1;head1=head2;head2=p;
cout<<"-";
substr();
}
}
else {
substr();
}
}
}
}
return 0;
}
京公网安备 11010502036488号