Решил научиться работать с алгоритмами длинной арифметики, и тут смотрю примеры, сложение впринципе понятна идея, а вот смотрю примеры с умножением двух больших чисел, там уже много непонятного и слишком все уж сложно. Даже не написано идея имножения.
А почему так все сложно сделано? нельзяли умножение заменить фызовом функции сложение через цикл до нужного числа?
Другие языки программирования и технологии
Длинная арифметика
Можно. Но долго. ОЧЕНЬ долго. Если цикл будет по переменной в 20 знаков, а компьютер выполняет миллиард операций в секунду, ждать придется 10^11 секунд.
Умножение в самом примитивном виде выполняют в столбик, но чаще оптимизируют, например так http://ru.wikipedia.org/wiki/Умножение_Карацубы
Умножение в самом примитивном виде выполняют в столбик, но чаще оптимизируют, например так http://ru.wikipedia.org/wiki/Умножение_Карацубы
Павел Беляев
спасибо, забавное название))
У-у-у, какой ты, оказывется, неграмотный. Фызов...
Да вроде там нет проблем с умножением
#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;
}
#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;
}
Похожие вопросы
- Длинная арифметика - продолжение
- Расскажите что-нибудь на тему арифметики длинных чисел на MIPS ассемблере?
- Почему практически все уроки и задачи на с/с++ в основном на арифметику и работу со строками и файлами?
- Алгоритмы перевода чисел из одной системы счисления в другую, арифметика в различных системах счисления
- СРОЧНО! Вопрос жизни и смерти Как умножать длинные числа на паскале?! При умножение иногда выдает переполнение ячейки.
- Возможно ли это снять на длинной выдержке иди это все же фотошоп?
- 1. Получить сумму двух длинных натуральных чисел.
- Как загрузить очень длинный аватар на сайте В контакте? Чтобы не писалось: Загрузка неудачна. Фотография слишком велика
- Пожалуйста,помогите написать программу,которая определяет длину самой длинной подстроки из подряд стоящих букв "с"!
- Как в Excel распечатать длинную таблицу на одном листе, и желательно с крупным шрифтом?