Bir bilgisayar mühendisi için programlama dili, öğrendiklerini sınadığı, deneyler yaptığı bir laboratuardır ve mühendisler deneylerini, kestiremedikleri sonuçları gözlemlemek için değil, öngördükleri sonuçları doğrulamak için yapar...

Uzun Tamsayı Sınıfı

Basamak sayısı sınırı olmadan tamsayılar üzerinde çarpma, toplama, bölme ve faktöryel alma işlemlerinin yapılabilmesini sağlayan cpp 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>
#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;
}
Sayfayı
Yayın tarihi: 31 Ocak 2010 Pazar, 09:32
Anahtar kelimeler: cpp uzun tamsayı sınıfı, yüzlerce basamaklı sayılar, büyük sayılarda işlem yapma

Yorum Gönder

 
Yorumunuzu -1. yoruma yanıt olarak gönderiyorsunuz. Yanıtlamayı iptal etmek için buraya tıklayabilirsiniz.

 

Yorumlar (3)

mustafa
Yanıtla
27 Aralık 2010 Pazartesi, 20:51
#1

Ç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 :)

Hüseyin Atasoy
Yanıtla
27 Aralık 2010 Pazartesi, 22:16
#2

Zaman bulursam bu kategoriyi kod örnekleriyle dolduracağım.

mustafa
Yanıtla
30 Aralık 2010 Perşembe, 13:44
#3

Bizler için çok iyi olur. Kolaylıklar dilerim şimdiden..Teşekkürler.

 
 
Sayfa 39 sorgu ile 0.01 saniyede oluşturuldu.
Atasoy Blog v4 © 2008-2017 Hüseyin Atasoy