![er](/Static/forum/img/rozet/tegmen.png)
C dilinde 100 faktöriyel hesaplama
#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++; } }Kod
Yığını:
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; }Kod
Yığını:
Ş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; }Kod
Yığını:
ş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; }Kod
Yığını:
Bu kod, 2345 ile 3'ü çarpmaktadır. Çıktı olarak 7035 verir. Şimdi satır satır kodu inceleyelim:
for(i=0; i<basamakSayisi; i++)
Döngü içinde i değişkeni basamakSayisi'na varana kadar bir bir artarak gidiyor.
int sayi = fakt[i]*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[i] = (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.
if(i == basamakSayisi-1 && elde>0)
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; }Kod
Yığını:
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:
Kod
Yığını:
#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; }Kod
Yığını:
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.
Son Giriş: 3 yıl önce
Son Mesaj Zamanı: 4 yıl
Mesaj Sayısı: 4
Gerçek Toplam Mesaj Sayısı: 4
İkinci El Bölümü Mesajları: 0
Konularının görüntülenme sayısı: 1.237 (Bu ay: 14)
Toplam aldığı artı oy sayısı: 0 (Bu hafta: 0)
En çok mesaj yazdığı forum bölümü: Yazılım Geliştirme
![](/static/forum/img/yukleniyor.gif)
![](/static/forum/img/yukleniyor.gif)