吐槽:
关于它给我弄不会了,我的脑海里上演一场数学大厦崩溃的大剧。
问题点:
后来发现是%d和%lld的问题。sscanf和printf这两个小烧杯;
int是四字节;long long是八字节;
他们的正整数表达没问题,但是他们的负数表达就有大问题了;
当前,计算机内部储存方式是以二进制形式。我们将int和long long以二进制角度展开考虑问题;
联系一个远古的知识店——补码。在int里的负数在long long里就会发现天翻地覆的改变;
思路:
把整数-整数的问题拆解为:
①4个小问题:正正、正负、负正、负负;
②1个关键公式:A-B=-(B-A);
其中我把正负性用类似补码形式另外储存->结构体里的sign(1,-1);
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#define int64 long long
#define i8 100000000
using namespace std;
struct number_struct{
int64 part[10000]={0};
int64 sign=1;
int count=0;
void show();
number_struct &operator = (char s[]){
int i;
char fmt[]="%8lld";
memset(part,0,sizeof(part));
i=strlen(s)-8;
for(;i>0;i-=8){
sscanf(s+i,fmt,part+count);
count++;
}
i=i+8;
fmt[1]=i+'0';
if(i==1){
if(s[0]=='-') sign=-1;
else if(s[0]!='-'){
sscanf(s,fmt,part+count);
count++;
}
}
else if(i>1){
if(s[0]=='-'){
sign=-1;
sscanf(s,fmt,part+count);
part[count]*=-1;
count++;
}
else if(s[0]!='-') sscanf(s,fmt,part+count);
}
return *this;
}
};
number_struct operator - (number_struct a,number_struct b){
number_struct c;
int i,j; // i 循环数 j 循环变量
int64 d,c_sum; // d 单元间差 sum单元差
i=a.count>=b.count?a.count:b.count;
c.count=i,c.sign=a.sign,d=0;
memset(c.part,0,sizeof(c.part));
for(j=0;j<i;j++){
//printf(" a.part[j]:%lld\n a.part[j]*a.sign:%lld\n b.part[j]:%lld\n b.part[j]*b.sign:%lld\n",a.part[j],a.part[j]*a.sign,b.part[j],b.part[j]*b.sign);
c_sum=(a.part[j]*a.sign-b.part[j]*b.sign+d)*c.sign;
//printf("---c_sum/c.sign:%lld c_sum:%lld d:%lld ---\n",c_sum,c_sum,d);
if(c_sum>=0) {d=c_sum/i8*c.sign,c_sum=c_sum%i8;}
else if(c_sum<0) {d=-1*c.sign,c_sum=c_sum+i8;}
c.part[j]=c_sum;
}
d*=c.sign;
if(d>=0) c.count+=d,c.part[j]=d;
else if(d<0){
memset(c.part,0,sizeof(c.part));
d=0,c.sign*=-1;
for(j=0;j<i;j++){
c_sum=(a.part[j]*a.sign-b.part[j]*b.sign+d)*c.sign;
if(c_sum>=0) {d=c_sum/i8*c.sign,c_sum=c_sum%i8;/*printf("%d>=0 c_sum:%d d:%d\n\n",c_sum,c_sum,d);*/}
else if(c_sum<0) {/*printf("%d<0 c_sum:%d d:%d\n\n",c_sum,c_sum,d)*/;d=-1*c.sign,c_sum=c_sum+i8;}
c.part[j]=c_sum;
}
}
j=c.count-1;
while(c.part[j--]==0&&c.count>1) c.count--;
return c;
}
void number_struct::show(){
int i;
i=count-1;
if(sign==-1) printf("-%lld",part[i]);else printf("%lld",part[i]);
for(i--;i>=0;i--) printf("%08lld",part[i]);
}
int main(){
char a[1000]={0};
char b[1000]={0};
number_struct x,y,z;
cin>>a;
cin>>b;
x=a;
y=b;
z=x-y;
z.show();
}
结语:
珍爱生命,远离编程。