Другие языки программирования и технологии

Длинная арифметика

Решил научиться работать с алгоритмами длинной арифметики, и тут смотрю примеры, сложение впринципе понятна идея, а вот смотрю примеры с умножением двух больших чисел, там уже много непонятного и слишком все уж сложно. Даже не написано идея имножения.

А почему так все сложно сделано? нельзяли умножение заменить фызовом функции сложение через цикл до нужного числа?
Павел Беляев
Павел Беляев
4 674
Можно. Но долго. ОЧЕНЬ долго. Если цикл будет по переменной в 20 знаков, а компьютер выполняет миллиард операций в секунду, ждать придется 10^11 секунд.
Умножение в самом примитивном виде выполняют в столбик, но чаще оптимизируют, например так http://ru.wikipedia.org/wiki/Умножение_Карацубы
Странник
Странник
73 470
Лучший ответ
Павел Беляев спасибо, забавное название))
У-у-у, какой ты, оказывется, неграмотный. Фызов...
Игорь Ленев
Игорь Ленев
70 263
Да вроде там нет проблем с умножением

#include <iostream>
using namespace std;

class dl
{ char* u;
int s;
int r;
public:
dl():s(1),r(3) { u=new char[r]; u[0]='0'; u[2]=u[1]=0; }
dl(char* x);
dl(const dl& x);
dl(int n) { u=new char[r=n]; s=u[0]=0; }
~dl() { delete [] u; r=s=0; u=NULL; }
void sets();
char& operator[](int i) { if(i>=0&&i < r) return u[ i ]; else { cerr << "err index" << endl; exit(1); u[0]=0; return u[0]; } }
dl& operator=(const char* x);
dl& operator=(const dl& x);
void abs(const dl& x);
dl operator-() const;
friend ostream& operator << (ostream& out,const dl& a) { out << a.u; return out; }
int eqp(const dl& b);
void mulp(const dl& x,const dl& y);
dl operator*(const dl& b);
};

void dl::sets()
{
for(s=0;s < r;) if(!u[++s]) break;
}

dl::dl(char* x)
{ int i=0;
for(r=0;x[r++];); s=r-1;
if(x[0]!='-') r++;
u=new char[r];
for(;i-s;u[ i ]=x[ i++ ]);
for(;i-r;u[ i++ ]=0);
}

dl::dl(const dl& x)
{ int i=0;
s=x.s; r=s+1; if(x.u[0]!='-') r++;
u=new char[r=x.r];
for(;i-r;u[ i ]=x.u[ i++ ]);
}

dl& dl::operator=(const dl& x)
{
if(this!=&x)
{ int i=0;
delete [] u;
s=x.s; r=s+1; if(x.u[0]!='-') r++;
u=new char[r=x.r];
for(;i-r;u[ i ]=x.u[ i++ ]);
}
return(*this);
}

dl& dl::operator=(const char* x)
{ int i=0;
for(r=0;x[r++];); s=r-1;
if(x[0]!='-') r++;
delete [] u;
u=new char[r];
for(;i-s;u[ i ]=x[ i++ ]);
for(;i-r;u[ i++ ]=0);
return(*this);
}

void dl::abs(const dl& x)
{ int j=0,i=0;
if(x.u[0]=='-') i=1;
delete [] u;
u=new char[r=x.r];
for(s=x.s-i;u[j++]=x.u[ i++ ];);
}

dl dl::operator-() const
{ int i; dl c(r); c[0]='-';
if(u[0]=='0'&&u[1]==0) c[0]='0',c[1]=c[2]=0;
else
if(u[0]=='-') for(i=0;c[ i++ ]=u[ i+1 ];);
else for(i=1;c[ i++ ]=u[ i-1 ];);
c.sets();
return dl(c);
}

int dl::eqp(const dl& x)
{ int i,t=0;
if(s!=x.s) return 0;
else for(i=0;i-s;t|=u[ i ]^x.u[ i++ ]);
return! t;
}

void dl::mulp(const dl& x,const dl& y)
{ int i,j,k,m,l,t;
char* a=new char[x.s];
char* b=new char[y.s];
char* c=new char[x.s+y.s];
for(i=0;i-x.s;a[ i++ ]=x.u[ i ]);
for(i=0;i-y.s;b[ i++ ]=y.u[ i ]);
for(i=0;i-x.s-y.s;c[ i++ ]='0');
for(t=0,l=y.s-1;l>=0;l--,t++)
{
for(i=x.s-1,j=x.s+y.s-1,k=0;i>=0;i--,j--)
k+=(x.u[ i ]-48)*(y.u[l]-48),k+=c[j-t]-48,c[j-t]=k % 10+48,k/=10;
for(;k;j--) k+=c[j-t]-48,c[j-t]=k % 10+48,k/=10;
}
for(i=0;i < x.s;i++) if(c[ i ]!='0') break;
delete [] u; u=new char[r=x.s+y.s-i+2];
for(j=0;i < x.s+y.s;u[j++]=c[ i++ ]); u[j]=0; sets();
delete [] a,b,c;
}

dl dl::operator*(const dl& x)
{
dl c,a,b;
int s=!(u[0]^'-')+2*!(x.u[0]^'-');
a.abs(*this);
b.abs(x);
c.mulp(a,b);
if(s*(s-3)) c=-c;
b="0"; a.abs(c); if(a.eqp(b)) c="0";
return dl(c);
}

int main()
{
int i;
//for(i=0;i < 100000;i++)
{
dl c,k,z;
z="123";
k="23"; c=k*z; cout << k << " * " << z << " = " << c << endl;
k="-23"; c=k*z; cout << k << " * " << z << " = " << c << endl;
z="-123"; c=k*z; cout << k << " * (" << z << ") = " << c << endl;
k="23"; c=k*z; cout << k << " * (" << z << ") = " << c << endl;
z="-23"; c=k*z; cout << k << " * (" << z << ") = " << c << endl;
z="-0"; c=k*z; cout << k << " * (" << z << ") = " << c << endl;
k="-0"; c=k*z; cout << k << " * (" << z << ") = " << c << endl;
k="-12"; c=k*z; cout << k << " * (" << z << ") = " << c << endl;
k="123456789123456789123456789123456789123456789123456789123456789123456789123456789";
z="999999943756843875643265375893275937953728953289578937589375893589347589375893758937";
c=k*z; cout << k << " * " << z << " = " << c << endl;
}
return 0;
}

Похожие вопросы