
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>
#include <stdlib.h> // itoa için
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)
{
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(){}
//constructor overloading; direk atama yapılmak istenirse
uzunts(string degeri){ sayi=degeri; }
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;
//iki rakamın ve eldenin toplamı en çok
//9+9+9=27 olur yani 2 basamaklı.
char b[3];
itoa(tplm,b,10);
snc.insert(0,b);
if(tplm>=10) //Eğer toplam 2 basamaklıysa
{
//onlar basamağı elde olacak
elde=atoi((snc.substr(0,1)).c_str());
//diğeri de sonuca ait bir rakam
sonuc.sayi.insert(0,snc.substr(1,1));
}
else
{
elde=0;
//demek ki tek basamaklı
sonuc.sayi.insert(0,snc.substr(0,1));
}
}
//En son kalan 0 değilse başa koy.
if(elde!=0) sonuc.sayi.insert(0,snc.substr(0,1));
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,
//sonra 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[3];
rakam1=atoi((sayi1.substr(i,1)).c_str());
rakam2=atoi((sayi2.substr(i,1)).c_str());
fark=rakam1-rakam2-komsudan;
//Onluğu alındığı halde hala büyükse veya eşitse
if(rakam1-komsudan>=rakam2)
{
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;
//sondaki sıfıra kadar, soldaki tüm sıfırları sil
for(i=0; i<uzunluk-1; i++)
if(sonuc.sayi.at(i)!='0') break;
sonuc.sayi.erase(0,i);
//küçük-büyük istenmişse - koy
if(eksi==true) sonuc.sayi.insert(0,"-");
return sonuc; //geçmiş olsun, hesap tamamlandı...
}
uzunts operator * (uzunts x)
{
//tektek, alttaki her rakamın üstteki sayı ile çarpımını tutacak.
uzunts sonuc,tektek;
string snc,sifirekle,sayi1=sayi,sayi2=x.sayi;
int rakam1,rakam2,tplm,elde=0;
int uzunluk=sayi.length(),uzunluk2=sayi2.length();
char b[3];
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
{
//onlar basamağı elde olacak
elde=atoi((snc.substr(0,1)).c_str());
tektek.sayi.insert(0,snc.substr(1,1));
}
else
{
elde=0;
tektek.sayi.insert(0,snc.substr(0,1));
}
snc="";
}
//En son kalan 0 değilse başa koy.
if(elde!=0) tektek.sayi.insert(0,itoa(elde,b,10));
tektek.sayi.insert(tektek.sayi.length(),sifirekle);
//burada classa ait yukardaki + operatorünü kullanmış oluyoruz.
sonuc=sonuc+tektek;
tektek.sayi="";
elde=0;
//Hani çarpmada alttaki sayıda her basamak atlandığında
//çarpımı 1 basamak sola kaydırıyoruz ya, bu da o
sifirekle.append(1,'0');
}
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);
//alinan sayi 1den büyükken...
while(hangisibuyuk(alinan.sayi,bir.sayi,uzunluk)==1)
{
sonuc=sonuc*alinan;
alinan=alinan-bir;
//whiledaki hangisibuyuk fonksiyonu için
basamakesitle(alinan.sayi,bir.sayi,uzunluk);
}
int i;
uzunluk=sonuc.sayi.length();
//basamak eşitlemeden kaynaklanan soldaki değersiz
for(i=0; i<uzunluk-1; i++)
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;
}Çok güzel bir program olmuş, ellerinize sağlık. C üzerine birkaç örnek daha olsa çok güzel olur. Şuan her ne kadar anlayamasakta inşallah ileride anlayabiliriz :)
Bizler için çok iyi olur. Kolaylıklar dilerim şimdiden..Teşekkürler.