Arama butonu
Bu konudaki kullanıcılar: 1 misafir, 1 mobil kullanıcı
0
Cevap
725
Tıklama
0
Öne Çıkarma
C dilinde 100 faktöriyel hesaplama
D
5 yıl
Er
Konu Sahibi

#include <stdio.h>
#include <stdlib.h>

//               ----- PROGRAMIN ACIKLAMASI -----               //
/*100! faktoriyel yaklasik 160 basamakli bir tamsayidan olusur 
ve bunu hicbir degiskene sigdiramayiz. Bu yuzden sayimizi bir diziye atayacagiz.
Program su sekilde calisacak:
fact[] adli diziye her seferinde hesaplanan sayi yazdirilacak, yani dizide 
saklanan ilk deger fact[0] = 1 iken ikinci islemde fact[0] = 2 olacak, üçüncü 
islemde de fact[0] = 6 ... seklinde degerler burada saklanacak ama sayilari tersten
yazdiracagiz, yani sayinin son basamagi dizinin 0. (fact[0]) elemaninda sakli olacak.
Bunu neden yaptigimi asagidaki fonksiyonda anlatacagim. Bu sekilde asagida j degiskeni
ile yaptigim dongude 1'den 100'e kadar carpma fonksiyonuna gidip j degiskeni ile fact[] 
icindeki sayiyi carparak faktoriyelini alacak. En sonunda j = 100 oldugunda fact[] icindeki 
sayiyla 100'u carpacak ve sayiyi ekrana yazdirip programi sonlandiracak. Eger sorun olursa 
yazabilirsin. Hadi programa gecelim :)
*/

int fact[200]; // Faktöriyelin saklandigi dizi
int numberOfDigit = 1; //faktoriyelin anlik karakter sayisini sakladigimiz degisken

int mult(int multiplier); // carpma islemi yapan fonksiyon 

int main()
{
int i; //sayacimiz
int multiplier = 1; //multiplier yani carpan

fact[0] = 1; // ilk degeri 1 yaptik

for(multiplier = 1; multiplier<=100; multiplier++)
{
mult(multiplier); // mult() fonksiyonuna gidelim
}
    printf("factoriel of 100 (100!): \n");
    for(i=numberOfDigit-1; i>=0; i--) // tersten yazdiriyoruz
    {
        printf("%d",fact[i]);
    }

    return 0;
}

int mult(int multiplier){

int carry = 0; // tipki kucukken yaptigimiz gibi carpma isleminde kullandigimiz 'elde'
int i = 0;

for(i=0; i<numberOfDigit; i++)
    {
        int x = fact[i]*multiplier; //product
        fact[i] = (x+carry)%10;
        carry = (x+carry)/10; // elde var 'carry'
   
        if (i == numberOfDigit-1 && carry>0)
            numberOfDigit++;
    }
}
Herkese iyi çalismalar, ben Fatih Dag. Bu forumda yazdigim (genellikle internette örnegini bulamadigim) kodlari paylasacagim. Programlamada Türkçe kaynaklara bir katkim olsun diye böyle bir seye karar verdim.

Bu programda 100 faktöriyeli hesaplayan bir program yazdım. Bu programı neden bu kadar uzattığıma gelirsek 100 faktöriyeli hesaplayıp bir değişkene atayamayız, nedeni ise sudur: Bütün programlama dillerinde veri tiplerinin bir siniri vardır. C dilinde ise en büyük veriyi tutabilen veri tipi unsigned long long int ve tutabildiği maksimum değer 18,446,744,073,709,551,615 idir.

 Simdi birde 100! sayisina bakalim:
100! = 93326215443944152681699238856266700490715-
9682643816214685929638952175999932299156089-
4146397615651828625369792082722375825118521-
0916864000000000000000000000000

Evet görüldüğü üzere 158 basamaktan oluşan sayı unsigned long long int veri tipinin bile çok üstünde bir sayı, simdi gelelim akıllardaki soruya, biz bu sayıyı nasıl depolayacağız?

Bunun için gereken çözüm dizilerde. Sayıyı diziye depolayacağız ve diziyi ekrana yazdıracağız. Gelelim işi nasıl yapacağımıza:

Aslında iş çok basit, ilkokulda öğrendiğimiz çarpma işlemini yapacağız ama kağıt üzerinde çarpıyormuş gibi, örneğin 2345 ile 5'i çarpalım:

2345    3*5 = 15
x   3    alt kısma 5 yazılır ve elde 1 kalır. Yani 15'in 5'ini alıyoruz, 1'i kalıyor
-----   elde var 1
    5
   

2345    3*4 = 12 + 1(elde var 1)
x   3    alt kisma 3 yazilir ve elde 1 kalir. 13'ün 3'ü yazilir, 1'i kalir
-----   elde var 1
   35


2345    3*3 = 9 + 1(elde var 1)
x   3    alt kisma 0 yazilir ve elde 1 kalir. 10'un 0'i yazilir 1'i elde kalir
-----   elde var 1
 035


2345    3*2 = 6 + 1(elde var 1)
x   3    alt kisma 7 yazilir ve elde bir sey kalmaz ve islem biter.
-----    
7035

Simdi bu işlemleri programa dökecegiz, öncelikle sayiyi tutacagimiz bir diziye ihtiyacimiz var, bu diziye sayımızı atayacağız ama sayıyı ters bir şekilde atamamız gerek, yani sayılarımızı hep [5,4,3,2] şeklinde saklayacağız. Bunun nedenini daha sonra açıklayacağım:

#include <stdio.h>
#include <stdlib.h>
#define MAX_DIGIT 200 

int main(){

int fakt[MAX_DIGIT] = {5, 4, 3, 2}; // yukarida MAX_DIGIT'i 200 olarak tanimladik

return 0;
Şimdi işlem yaparken elde kalanları taşıyacağımız ve dizinin sonunu bilmemizi sağlayacak iki değişkene ihtiyacımız var. Birde sayaç oluşturacağız.
#include <stdio.h>
#include <stdlib.h>
#define MAX_DIGIT 200 

int main(){

int fakt[MAX_DIGIT] = {5, 4, 3, 2};
int basamakSayisi = 4; // Basamak sayısını tutan değişkenimiz
int elde = 0; // elde
int i = 0; // sayacımız

return 0;
şimdi gelelim programın asıl kısmına:
#include <stdio.h>
#include <stdlib.h>
#define MAX_DIGIT 200 

int main(){

int fakt[MAX_DIGIT] = {5, 4, 3, 2};
int basamakSayisi = 4; // Basamak sayısını tutan değişkenimiz
int elde = 0; // elde
int i = 0; // sayacımız

for(i=0; i<basamakSayisi; i++)
{
    int sayi = fakt[i]*3; //3 burada çarpanımnız olur
    fakt[i] = (sayi+elde)%10;
    elde= (sayi+elde)/10; // elde var 'carry'
   
    if (i == basamakSayisi-1 && elde>0)
        basamakSayisi++;
}
return 0;
Bu kod, 2345 ile 3'ü çarpmaktadır. Çıktı olarak 7035 verir. Şimdi satır satır kodu inceleyelim:

<span style="color:#a10000">for(i=0; i<basamakSayisi; i++) </span>
Döngü içinde i değişkeni basamakSayisi'na varana kadar bir bir artarak gidiyor.

int sayi = fakt*3;
Burada sayımızın birler basmağı ile çarpanımızı çarpıyoruz.Yani şu işlemi 3x5 =15
2345
x 3
-----
5
yapıyoruz.

fakt = (sayi+elde)%10;
Burası önemli, burada sonucumuzun(7035) birler basamağını buluyoruz. (sayi+elde)%10 işleminde sayi'yi ilk işlemde yaptığımız gibi 15 farz edelim, (15+0)%10 işleminin sonucu 5'tir yani sayımızın birler basamağıdır. bu sayıyı dizinin ilk indeksine, daha sonra ise 2. 3. ve 4. indekslerine atayacağız.

elde = (sayi+elde)/10;
Burada elde kalan sayı hesaplanıyor, yani 15'in 1'i alınıyor ve elde'ye atanıyor. birkaç örnek sayıyı kendiniz deneyerek anlattıklarımı daha iyi anlayabilirsiniz.

<span style="color:#a10000">if(i == basamakSayisi-1 && elde>0)</span>
basamakSayisi++;
Bu kod bloğunda sayacımız basamakSayisi-1'e eşit olduğunda yani son döngüye girdğinde elde'de sayı kalmışsa döngüyü 1 erteliyor.

çarpma işlemini öğrendiğimize göre şimdi sonucu ekrana yazdıralım:
#include <stdio.h>
#include <stdlib.h>
#define MAX_DIGIT 200 

int main(){

int fakt[MAX_DIGIT] = {5, 4, 3, 2};
int basamakSayisi = 4; // Basamak sayısını tutan değişkenimiz
int elde = 0; // elde
int i = 0, j = 0; // sayaclarımız

for(i=0; i<basamakSayisi; i++)
{
    int sayi = fakt[i]*3; //3 burada çarpanımnız olur
    fakt[i] = (sayi+elde)%10;
    elde= (sayi+elde)/10; // elde var 'carry'
   
    if (i == basamakSayisi-1 && elde>0)
        basamakSayisi++;
}

for(j = basamakSayisi-1; j>=0; j--)
{
printf("%d", fakt[j]);
}

return 0;
Sayıyı ters yazdığımız için diziyi sondan yazıyoruz.

Şimdi geldik 100! hesaplamaya, program her çarpma işleminde dizinin içindeki sayı ile bizim 3 diye belirttiğimiz çarpanı çarpıyor ve tekrar diziye atıyor. Şimdi bizim yapmamız gerek şu: Önce diziye başlangıç değeri olarak 1 atayacağız ve bir döngü açıp döngünün 1'den 100'e kadar artmasını sağlayacağız. Program her seferinde döngüdeki değişkeni(i) alıp dizinin içindeki sayı ile çarpacak ve tekrar diziye atayacak.
Başlayalım:





#include <stdlib.h>
#include <stdio.h>
#define MAX_DIGIT 200 

int main(){

 int fakt[MAX_DIGIT] = {1};
 int basamakSayisi = 4; // Basamak sayısını tutan değişkenimiz
 int elde = 0; // elde 
 int i = 0, j = 0; // sayaclarımız
 int carpan = 1;  

 for(carpan = 1; carpan <=100; carpan++)
 {
  for(i=0; i<basamakSayisi; i++)
  {
   int sayi = fakt[i]*carpan; //carpan her asamada bir artiyor
   fakt[i] = (sayi+elde)%10;
   elde= (sayi+elde)/10; // elde var 'carry'

   if (i == basamakSayisi-1 && elde>0)
     basamakSayisi++;
  }
 }
 
 for(j = basamakSayisi-1; j>=0; j--)
 {
   printf("%d", fakt[j]);
 }

return 0;
}
Evet bir döngü oluşturduk ve döngüde carpan adlı değişkeni bir bir artırdık ve her aşamada dizideki sayı ile çarptık, yani işlem aslında şu şekilde:
fakt = 1x1 = 1
fakt = 1x2 = 2
fakt = 2x3 = 6
fakt = 6x4 = 24
...
fakt = 100!

Evet program burada sona eriyor. Benim yazdığım en üstteki program daha farklı,çünkü benim kod yazma tarzımla yazdım ve fonksiyon kullandım. Bu konuda size mantığını anlattım, sizde istediğiniz gibi yazabilirsiniz. Eğer bir eksiğim veya bir sorunuz olursa çekinmeyin, teşekkürler :D

Bu programı yabancı bir kaynaktan da alıntı yaparak yazdım, buradan yabancı kaynağa ulaşabilirsiniz.

DH forumlarında vakit geçirmekten keyif alıyor gibisin ancak giriş yapmadığını görüyoruz.

Üye olduğunda özel mesaj gönderebilir, beğendiğin konuları favorilerine ekleyip takibe alabilir ve daha önce gezdiğin konulara hızlıca erişebilirsin.

Üye Ol Şimdi Değil



DH Mobil uygulaması ile devam edin. Mobil tarayıcınız ile mümkün olanların yanı sıra, birçok yeni ve faydalı özelliğe erişin. Gizle ve güncelleme çıkana kadar tekrar gösterme.