Bu sınıf yardımıyla sınırsız sayıda basamak içeren uzun tamsayılar oluşturabilir ve bu sayılarla toplama, çıkarma, çarpma gibi işlemler yapabilirsiniz. Ek olarak sınıf içerisinde, 4 basamaklı sayıların bile faktöryellerini hesaplayacak bir de fonksiyon var. Örneğin 1009 sayısının faktöryeli 27 saniyede hesaplandı ve sonuçta tam 2596 basamaklı bir sayı çıktı. Herhangi bir taşma olmaması için işlemlerin tümünü rakam rakam yaptırdım ve bölme işleminde rakam rakam gidilebilecek bir yöntem bulamadığımdan bölme işlemini tanımlamadım...
#include <iostream>
#include <string>
using namespace std;
class uzunts
{
/*
Hüseyin Atasoy
www.atasoyweb.net
21/12/2009
*/
//İki sayının biri diğerinden daha az basamak taşıyorsa ona 0 ekler.
//örneğin 12 ve 3, 12 ve 03 olur.
void basamakesitle(string& sayi1, string& sayi2, int& uzunluk) //Burada uzunluk ta hesaplanacak
{ //o yüzden adresiyle gönderiyorum
if(sayi1.length()>sayi2.length())
{
uzunluk=sayi1.length();
string ekle;
ekle.append(uzunluk-sayi2.length(),'0');
sayi2.insert(0,ekle);
}
else
{
uzunluk=sayi2.length();
string ekle;
ekle.append(uzunluk-sayi1.length(),'0');
sayi1.insert(0,ekle);
}
}
//String tipinde eşit basamaklı iki sayıyı karşılaştırır. En anlamlı
//rakamlardan birbirlerine eşit olmayanlara rastladı mı sonuç döndürür.
int hangisibuyuk(string& sayi1, string& sayi2, int uzunluk)
{
int rakam1,rakam2;
for(int i=0; i<uzunluk; i++)
{
rakam1=atoi((sayi1.substr(i,1)).c_str());
rakam2=atoi((sayi2.substr(i,1)).c_str());
if(rakam1>rakam2) return 1; //ilk sayı daha büyük
if(rakam1<rakam2) return 2; //ikinci sayı daha büyük
}
return 0; //buraya gelirse eşitler demektir, o zaman 0 döndür...
}
public:
string sayi;
uzunts(){}
uzunts(string degeri){ sayi=degeri; } //constructor overloading; direk atama yapılmak istenirse
uzunts operator + (uzunts x)
{
uzunts sonuc("");
int rakam1,rakam2,tplm,uzunluk,elde=0;
string snc,sayi1=sayi,sayi2=x.sayi;
basamakesitle(sayi1,sayi2,uzunluk);
for(int i=uzunluk-1; i>-1; i--)
{
snc=""; //her seferinde tekrar kullanmak için boşalt.
rakam1=atoi((sayi1.substr(i,1)).c_str());
rakam2=atoi((sayi2.substr(i,1)).c_str());
tplm=rakam1+rakam2+elde;
char b[2]; //iki rakamın ve eldenin toplamı en çok 9+9+9=27 olur yani 2 basamaklı.
itoa(tplm,b,10);
snc.insert(0,b);
if(tplm>=10) //Eğer toplam 2 basamaklıysa
{
elde=atoi((snc.substr(0,1)).c_str()); //onlar basamağı elde olacak
sonuc.sayi.insert(0,snc.substr(1,1)); //diğeri de sonuca ait bir rakam
}
else
{
elde=0;
sonuc.sayi.insert(0,snc.substr(0,1)); //demek ki tek basamaklı
}
}
if(elde!=0) sonuc.sayi.insert(0,snc.substr(0,1)); //En son kalan 0 değilse başa koy.
return sonuc; //geçmiş olsun, hesap tamamlandı...
}
uzunts operator - (uzunts x)
{
uzunts sonuc("");
int rakam1,rakam2,fark,uzunluk,komsudan=0;
string snc,sayi1=sayi,sayi2=x.sayi;
bool eksi=false;
basamakesitle(sayi1,sayi2,uzunluk);
//Eğer küçük-büyük isteniyorsa büyük-küçük hesapla en son başına - eklersin.
if(hangisibuyuk(sayi1,sayi2,uzunluk)==2)
{
sayi2=sayi;
sayi1=x.sayi;
basamakesitle(sayi1,sayi2,uzunluk);
eksi=true;
}
for(int i=uzunluk-1; i>-1; i--)
{
char b[2];
rakam1=atoi((sayi1.substr(i,1)).c_str());
rakam2=atoi((sayi2.substr(i,1)).c_str());
fark=rakam1-rakam2-komsudan;
if(rakam1-komsudan>=rakam2) //Onluğu alındığı halde hala büyükse veya eşitse
{
itoa(fark,b,10);
komsudan=0;
}
else //altındaki rakamdan küçükse, komşudan onluk al.
{
itoa(10+fark,b,10);
komsudan=1;
}
snc.insert(0,b);
sonuc.sayi.insert(0,snc);
snc="";
}
int i;
for(i=0; i<uzunluk-1; i++) //sondaki sıfıra kadar, soldaki tüm sıfırları sil
if(sonuc.sayi.at(i)!='0') break;
sonuc.sayi.erase(0,i);
if(eksi==true) sonuc.sayi.insert(0,"-"); //küçük-büyük istenmişse - koy
return sonuc; //geçmiş olsun, hesap tamamlandı...
}
uzunts operator * (uzunts x)
{
uzunts sonuc,tektek; //tektek, alttaki her rakamın üstteki sayı ile çarpımını tutacak.
string snc,sifirekle,sayi1=sayi,sayi2=x.sayi;
int rakam1,rakam2,tplm,elde=0,uzunluk=sayi.length(),uzunluk2=sayi2.length();
char b[2];
for(int j=uzunluk2-1; j>-1; j--)
{
rakam2=atoi((sayi2.substr(j,1)).c_str());
for(int i=uzunluk-1; i>-1; i--)
{
rakam1=atoi((sayi1.substr(i,1)).c_str());
tplm=rakam1*rakam2+elde;
itoa(tplm,b,10);
snc.insert(0,b);
if(tplm>=10) //Eğer toplam 2 basamaklıysa
{
elde=atoi((snc.substr(0,1)).c_str()); //onlar basamağı elde olacak
tektek.sayi.insert(0,snc.substr(1,1));
}
else
{
elde=0;
tektek.sayi.insert(0,snc.substr(0,1));
}
snc="";
}
if(elde!=0) tektek.sayi.insert(0,itoa(elde,b,10)); //En son kalan 0 değilse başa koy.
tektek.sayi.insert(tektek.sayi.length(),sifirekle);
sonuc=sonuc+tektek; //burada classa ait yukardaki + operatorünü kullanmış oluyoruz.
tektek.sayi="";
elde=0;
sifirekle.append(1,'0'); //Hani çarpmada alttaki sayıda her basamak atlandığında
} //çarpımı 1 basamak sola kaydırıyoruz ya, bu da o
return sonuc; //geçmiş olsun, hesap tamamlandı...
}
//İşlemleri güzel gösteren bir fonksiyon da olsun bari :)
void goster(uzunts uzunts1, uzunts uzunts2, uzunts sonuc, string islem)
{
cout<<endl;
string ekle1,ekle2,ekle3;
ekle1.append(sonuc.sayi.length(),'-');
ekle2.append(sonuc.sayi.length()-uzunts1.sayi.length(),' ');
ekle3.append(sonuc.sayi.length()-uzunts2.sayi.length(),' ');
cout<<"\t"<<ekle2<<uzunts1.sayi<<endl;
cout<<" "<<islem<<"\t"<<ekle3<<uzunts2.sayi<<endl;
cout<<" ----"<<ekle1<<endl;
cout<<"\t"<<sonuc.sayi;
cout<<endl;
}
uzunts faktoryel(void)
{
uzunts alinan, sonuc("1"), bir("1");
int uzunluk;
alinan.sayi=sayi;
basamakesitle(alinan.sayi,bir.sayi,uzunluk);
while(hangisibuyuk(alinan.sayi,bir.sayi,uzunluk)==1) //alinan sayi 1den büyükken...
{
sonuc=sonuc*alinan;
alinan=alinan-bir;
basamakesitle(alinan.sayi,bir.sayi,uzunluk); //whiledaki hangisibuyuk fonksiyonu için
}
int i;
uzunluk=sonuc.sayi.length();
for(i=0; i<uzunluk-1; i++) //basamak eşitlemeden kaynaklanan soldaki değersiz
if(sonuc.sayi.at(i)!='0') break; //sıfırları sil
sonuc.sayi.erase(0,i);
return sonuc;
}
};
int main()
{
uzunts a("2334233532324883824928384");
uzunts b("48765984758787");
uzunts c;
c=a+b;
c.goster(a,b,c,"+"); //cout<<c.sayi<<endl;
cout<<endl<<endl;
c=a*b;
c.goster(a,b,c,"*");
cout<<endl<<endl<<"307! = ";
uzunts d("307");
cout<<(d.faktoryel()).sayi;
cout<<endl;
return 0;
} Okunma Sayısı: 205
Yayınlanma Tarihi: 31 Ocak 2010 Pazar - 09:32
Anahtar Kelimeler: c++, cpusplus, uzun tamsayı, sınıfı, toplama, çıkarma, çarpma, faktöryel
Onaylı yorum bulunmuyor.
Yorum/Görüş Bildir