Bir Bilgisayar Mühendisi İçin Programlama Dili, Öğrendiklerini Sınadığı, Deneyler Yaptığı Bir Laboratuardır. Ve Mühendisler Deneylerini, Kestiremedikleri Sonuçları Gözlemlemek İçin Değil, Öngördükleri Sonuçları Doğrulamak İçin Yaparlar...
Programlama Günlüğü > C, C++, CSharp > Uzun Tamsayı Sınıfı
C, C++, CSharp
 
Üye Girişi
E-mail:

Şifre:



 
Blog Arama Motoru
 
Son Güncellenenler
 
Sosyal Ağlarda Paylaş
 
Uzun Tamsayı Sınıfı
C++ ile uzun tamsayı sınıfı

   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ı: 634
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
Yorumları html kodu veya özel karakter kullanmadan, yazım kurallarına
dikkat ederek ve düzgün bir Türkçe kullanarak yazalım...
 
      Atasoy Blog v3.0 © 2009-2010 Hüseyin Atasoy | Tema Tasarımı: Hüseyin Atasoy
AtasoyWeb Firefox'u Önerir :) | Yukarı Çık