Witam!
Wiem, że kod długi, ale testowałem wszystkie operatory i wydaje mi się, ze dzialają poprawnie, więc pozostaje kwestia funkcji NWD. Nie mogę poradzić sobie ze znalezieniem błędu.
#include <iostream>
#include <cstring>
#define si short int
#define ui unsigned int
#define FOR(a, b, c) for(ui b=a; b<c; b++)
#define MAX(a, b) (a>b?a:b)
#define max_number_of_digits 2048
using namespace std;
struct BigNum
{
bool sign;
ui lenght;
si* digits;
BigNum ()
{
digits = new si[0];
lenght=0;
sign=0;
}
BigNum (si s, ui l, si* d)
{
digits = new si[max_number_of_digits];
lenght = l;
sign = s;
memmove(digits, d, max_number_of_digits*sizeof(si));
}
BigNum (si s, ui l, char* d)
{
digits = new si[max_number_of_digits];
lenght = l;
sign = s;
FOR(0, i, l)
digits[max_number_of_digits-(l-i+1)]=(si)(d[i]-'0');
}
BigNum (si s, ui l, string & d)
{
digits = new si[max_number_of_digits];
lenght = l;
sign = s;
FOR(1, i, l+1)
digits[max_number_of_digits-(i)]=(si)(d[l-(i)]-'0');
}
};
ostream & operator << (ostream & out, const BigNum & s)
{
for(ui i=s.lenght; i>0; i--)
out << s.digits[max_number_of_digits-i];
return out;
}
istream & operator >> (istream & in, BigNum & s)
{
string tmp;
in >> tmp;
s=BigNum(0, tmp.size(), tmp);
return in;
}
BigNum operator+ (BigNum & a, BigNum & b)
{
si* tmp=new si[max_number_of_digits];
FOR(0, i, 2048) tmp[i]=0;
for(ui i=max_number_of_digits-1; i>max_number_of_digits-(MAX(a.lenght, b.lenght)+1); i--)
{
tmp[i]+=a.digits[i]+b.digits[i];
if(tmp[i]>=10)
{
tmp[i-1]=tmp[i]/10;
tmp[i]%=10;
}
}
return BigNum(a.sign*b.sign, MAX(a.lenght, b.lenght)+(tmp[max_number_of_digits-(MAX(a.lenght, b.lenght))]==0?1:0), tmp);
}
BigNum operator- (BigNum & a, BigNum & b)
{
si* tmp=new si[max_number_of_digits];
for(ui i=max_number_of_digits-1; i>max_number_of_digits-(MAX(a.lenght, b.lenght)+1); i--)
{
tmp[i]+=a.digits[i]-b.digits[i];
if(tmp[i]<0)
{
tmp[i-1]--;
tmp[i]+=10;
}
}
si num=0;
for(int i=max_number_of_digits-(MAX(a.lenght, b.lenght)+1); i<max_number_of_digits; i++)
if(tmp[i]!=0)
{
num=max_number_of_digits-i;
break;
}
num==0?num=1:0;
return BigNum(a.sign*b.sign, num, tmp);
}
bool operator < (BigNum & a, BigNum & b)
{
if(a.lenght!=b.lenght)
return a.lenght<b.lenght;
for(int i=max_number_of_digits-a.lenght-1; i<max_number_of_digits; i++)
if(a.digits[i]!=b.digits[i])
return a.digits[i]<b.digits[i];
return false;
}
bool operator == (BigNum & a, BigNum & b)
{
if(a.lenght!=b.lenght)
return false;
for(int i=max_number_of_digits-a.lenght-1; i<max_number_of_digits; i++)
if(a.digits[i]!=b.digits[i])
return false;
return true;
}
bool operator != (BigNum & a, BigNum & b)
{
return !(a==b);
}
bool operator<= (BigNum & a, BigNum & b)
{
if(a.lenght!=b.lenght)
return a.lenght<=b.lenght;
for(int i=max_number_of_digits-a.lenght-1; i<max_number_of_digits; i++)
if(a.digits[i]<b.digits[i])
return a.digits[i]<b.digits[i];
return false;
}
bool operator> (BigNum & a, BigNum & b)
{
return b<a;
}
bool operator>= (BigNum & a, BigNum & b)
{
return b<=a;
}
BigNum operator* (BigNum & a, int b)
{
if (b==2)
{
si* tmp=new si[max_number_of_digits];
FOR(0, i, 2048) tmp[i]=0;
for(ui i=max_number_of_digits-1; i>max_number_of_digits-a.lenght-1; i--)
{
tmp[i]+=a.digits[i]*2;
if(tmp[i]>=10)
{
tmp[i-1]=tmp[i]/10;
tmp[i]%=10;
}
}
return BigNum(a.sign, a.lenght+(tmp[max_number_of_digits-(a.lenght)]==0?1:0), tmp);
}
return BigNum();
}
BigNum operator/ (BigNum & a, int b)
{
si* tmp=new si[max_number_of_digits];
for(ui i=max_number_of_digits-(a.lenght); i<max_number_of_digits; i++)
{
tmp[i]+=a.digits[i];
if(tmp[i]%2==1)
tmp[i+1]+=10;
tmp[i]/=2;
}
si num;
for(int i=max_number_of_digits-(a.lenght+1); i<max_number_of_digits; i++)
if(tmp[i]!=0)
{
num=max_number_of_digits-i;
break;
}
num==0?num=1:0;
return BigNum(a.sign, num, tmp);
}
int operator% (BigNum & a, int b)
{
if(b==2)
{
return a.digits[max_number_of_digits-1]%2;
}
return 0;
}
bool operator== (BigNum & a, char b)
{
if(a.digits[max_number_of_digits-1]+'0'==b && a.lenght==1)
return true;
return false;
}
BigNum NWD(BigNum a, BigNum b)
{
si* tmp=new si[max_number_of_digits];
tmp[max_number_of_digits-1]=1;
BigNum zero(0, 1, tmp);
ui dwojki=0;
//cout << "dupa" <<endl;
if(a<b) swap(a, b);
while (!(b=='0') && !(b=='1'))
{
if(a%2==0 && b%2==0)
{
dwojki++;
a=a/2;
b=b/2;
cout << "(a%2==0 && b%2==0): " << a << ", " << b <<endl;
}
else if(a%2==1 && b%2==0)
{
b=b/2;
cout << "(a%2==1 && b%2==0): " << a << ", " << b <<endl;
}
else if(a%2==0 && b%2==1)
{
a=a/2;
cout << "(a%2==1 && b%2==0): " << a << ", " << b <<endl;
}
else if(a%2==1 && b%2==1)
{
a=a-b;
cout << "(a%2==1 && b%2==1): " << a << ", " << b <<endl;
}
//if(b==zero || a==zero) break;
if(a<b) swap(a, b);
}
while (dwojki--)
{
a=a*2;
}
return a;
}
int main ()
{
BigNum k, l;
int n;
cin >> n;
while (n--)
{
cin >> k >> l;
//cout << endl << "a: " << a << ", b: " << b << endl;
//a=a+a;
/*
cout << "a-b= "<< a-b << endl;
cout << "a+b= " << a+b << endl;
cout << "a<b? " << ((a<b)?"TAK":"NIE") << endl;
cout << "a<=b? " << ((a<=b)?"TAK":"NIE") << endl;
cout << "a==b? " << ((a==b)?"TAK":"NIE") << endl;
cout << "a*2= " << a*2 << endl;
cout << "b*2= " << (b*2) << endl;
cout << "a%2= " << (a%2) << endl;
cout << "b%2= " << (b%2) << endl;*/
cout << NWD (l, k) << endl;
}
}