* Önsöz
* Fortran'a Giriş
* Fortran'nın Temelleri
* Basit ve Formatlı Okuma/Yazma
* Temel Kütüphane Fonksiyonları
* Karşılaştırma Deyimleri
* Döngüler
* Alt Programlar I
* Alt Programlar II
* Diziler
* Dinamik Diziler
* Gösterici (Pointer) Kavramı
* Katarlar (Stringler)
* Yapısal Veri Tipleri
* Dosya Yönetimi
* Modül Kavramı
* Sayısal Tipler (KINDs)
* Bit Düzeyinde Çalışmak
* Kütüphane Fonksiyonları Listesi
* Yararlanılan Kaynaklar
* - - -
* Karmaşık Sayılar
* Tarih-Saat Fonksiyonları
* Rastgele Sayılar
* Katar - Sayı Dönüşümleri
* Komut Satırı İşlemleri
* Co-Array Fortran
* Derleme Seçenekleri
* Fortran ve C
* Sayılar Kuramı
* Analiz
* Lineer Cebir
Fortran 90/95 Derleyicileri
|
* Salford (silversoft FTN95)
* G95
* GFORTRAN
* programlama.com
* Fortran (wikipedia)
* fortran.gantep.edu.tr
* g95.org
* Hot scripts
* E-posta
|
|
Seçilmiş Örnekler: Sayılar Kuramı (Number Theory)
###################- (%95)
|
Giriş
Bu kısımda, sayılar kuramı ve programlama ile ilgili 5 klasik örnek işlenecektir.
17.1 Sayı Basamakları
n basamaklı, bj = 0, 1, ..., 9 olmak üzere,
bn ... b3 b2 b1
şeklinde pozitif bir tamsayı düşünelim. Böyle bir sayının birler basamağındaki rakam (b1), sayının 10 ile bölümünden kalandır. Örneğin:
1453 sayının 10 ile bölümünden kalan 3 tür. Buna göre birler basamağı Fortran'da şu şekilde bulunur.
b1 = MOD(bn ... b3 b2 b1, 10)
Eğer sayı 10'a bölünüp sonucun tam kısmını hesaplarsak birler basamağı devre dışı kalır ve
sayının basamak sayısı bir azalır. Örneğin INT(1453/10) = INT(145.3) = 145 gibi.
Bu iki işlem her basamak için tekrar edilirse, sayının kaç basamaktan oluştuğu ve her basamaktaki
rakam elde edilmiş olur.
Toparlarsak, n basamaklı bir sayının her bir basamağı ve kaç basamaklı oluğu aşağıdaki gibi tespit edilebilir:
Sayi: 1453
1. MOD(1453,10) = 3 ve 1453/10 = 145
2. MOD(145,10) = 5 ve 145/10 = 14
3. MOD(14,10) = 4 ve 14/10 = 1
4. MOD(1,10) = 1 ve 1/10 = 0 (son)
Son olarak 3, 5, 4 ve 1 rakamları 3*1000 + 5*100 + 4*10 + 1 = 3541 şeklinde yazılırsa,
orjinal sayımızın tersi elde edilmiş olur.
Program 17.1, yukarıda anlatılan yöntemlerle, klavyeden girilen bir tamsayının, basamaklarını ve
tersini bulup ekrana yazar. İnceleyiniz.
Program 17.1: Bir tam sayının basamakları ve tersi
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
|
PROGRAM Basamak
!-------------------------------------------------------
! 17prg01.f95
! Bir pozitif tamsayının basamakları ve tersi.
!-------------------------------------------------------
IMPLICIT NONE
INTEGER :: M, B, N, K, J, Sayi
PRINT *,"Pozitif bir tam sayı girin:"
READ *,Sayi
M = Sayi ! sayının kendisi
N = 0 ! tersi
K = 0 ! basamak sayısı
PRINT *
PRINT *,"Her basamaktaki rakam: "
DO WHILE( M>0 )
B = MOD(M,10) ! B birler basamağı
M = M / 10 ! Sayiyi 10'a böl (birler basamağnı at)
N = 10*N + B ! ve N sayınına ekle
K = K + 1 ! Basamak sayısını hesapla
J = 10**(K-1) ! basamak değeri
! Her bir basamak değeri ve basamağı ekrana yaz
PRINT '(I6," ler basamağı ",I3)',J, B
END DO
PRINT *
PRINT *,"Basamak Sayısı : ",K
PRINT *,"Sayının Tersi : ",N
END PROGRAM |
ÇIKTI
Pozitif bir tam sayı girin:
1453
Her basamaktaki rakam:
1 ler basamağı 3
10 ler basamağı 5
100 ler basamağı 4
1000 ler basamağı 1
Basamak Sayısı : 4
Sayının Tersi : 3541
|
17.2 Bir Tamsayının Asal Çarpanları
Bir tamsayının asal çarpanları o sayıyı tam bölen sayılardır. Örneğin 148 sayısının (1 ve kendisi dahil)
tam bölenleri 1, 2, 4, 23, 46 ve 92 dir. Tam bölenleri Fortran'da bulmak için imdadımıza yine MOD
fonksiyonu yetişir.
Program 17.2, bir sayının asal bölenleri, basit bir döngü içinde 1'den sayının
kendisine kadar bütün sayıları tek tek deneyerek bulur.
Program 17.2: Bir tam sayının basamakları ve tersi
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
|
PROGRAM Asal_Carpanlar
!----------------------------------------------
! 17prg02.f95
! Bir tamsayının 1 ve kendisi dahil
! asal çarpanları (tam bölenleri).
!----------------------------------------------
IMPLICIT NONE
INTEGER :: I, K, Sayi
PRINT *,"Pozitif bir tamsayı girin:"
READ *,Sayi
PRINT *,"Asal Çarpanlar:"
DO I = 1, Sayi
! Sayinin I ile bölümünden kalan
K = MOD(Sayi, I)
! Kalan sıfır mı?
IF(K == 0) PRINT *, I
END DO
END PROGRAM |
ÇIKTI
Pozitif bir tamsayı girin:
248
Asal Çarpanlar:
1
2
4
8
31
62
124
248
|
17.3 Palindromik Sayılar
Her simetrik sayı palindromik sayı olarak aklandırılır. Örneğin 22, 101, 9339, 812218
sayıları palindromiktir. Program 17.3 1 ile 1000 arasındaki bütün palindromik sayıları bulup ekrana
yazar.
Program 17.3: N = 1000'den küçük bütün Palindromik Sayılar.
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
|
PROGRAM Palindromik_Sayilar
!----------------------------------------------
! 17prg03.f95
! N = 1000'den küçük bütün Palindromik Sayılar.
!----------------------------------------------
IMPLICIT NONE
INTEGER, PARAMETER :: N = 1000
INTEGER :: M, B, Tersi, Sayi, Sayac = 0
DO Sayi = 1, N
M = Sayi
Tersi = 0
DO WHILE(M>0)
B = MOD(M, 10)
M = M / 10
Tersi = 10*Tersi + B
END DO
IF( Sayi == Tersi ) THEN
PRINT *,Sayi
Sayac = Sayac + 1
END IF
END DO
PRINT *,"Toplam ",Sayac, "tane."
END PROGRAM Palindromik_Sayilar
|
ÇIKTI
1
2
3
4
5
6
7
8
9
11
22
33
44
55
66
77
88
99
101
111
...
989
999
Toplam 108 tane.
|
17.4 Mükemmel Sayılar
Kendisi hariç, tam bölenlerin toplamı kendine eşit olan sayıya mükemmel sayı denir.
Bu tanıma göre aşağıdaki sayılar mükemmel sayıdır:
6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14
496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248
Program 17.4 1 ile 10,000 arasındaki bütün mükemmel sayıları bulup ekrana yazar.
Program 17.4: N = 10,000'den küçük bütün mükemmel sayılar.
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
|
PROGRAM Mükemmel_Sayi
!------------------------------------------------------
! 17prg04.f95
! N = 10000 den küçük mükemmel sayılar.
!------------------------------------------------------
IMPLICIT NONE
INTEGER, PARAMETER :: N = 10000
INTEGER :: I, Sayi, Toplam, Sayac = 0
DO Sayi = 2, N
Toplam = 0
DO I=2, Sayi-1
! tam bölenleri bul ve topla
IF( MOD(Sayi,I) == 0 ) Toplam = Toplam + I
END DO
! Bölenlerin toplamı sayıya eşit mi?
IF( Toplam + 1 == Sayi) THEN
Sayac = Sayac + 1
PRINT *,Sayi
END IF
END DO
PRINT *,"Toplam ",Sayac, " adet."
END PROGRAM Mü |
ÇIKTI
6
28
496
8128
Toplam 4 adet.
|
17.5 Asal Sayılar
Sadece iki tam bölene sahip tamsayılar asal sayı olarak adlandırılır. İlk bir kaç asal sayı şöyledir:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, ...
Asal sayıların bulunuşu için birçok algoritma mevcuttur. En yalını, sayıyı 1 den sayının değerine kadar
bölmek ve kalanları hesaplamakatır. Sayı, sadece iki tam bölene (1 ve sayının kendisi) sahipse,
sayı aşikar asaldır. Bu yavaş algoritmanın kotarılması Program 17.5'de gösterilmiştir. Program,
100,000 den küçük bütün asalları ekrana basar.
Program 17.5: N = 100,000'den küçük asal sayılar.
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
|
PROGRAM Asal_Sayilar
!----------------------------------------------------
! 17prg05.f95
! N = 100,000 den küçük asal sayılar.
!----------------------------------------------------
IMPLICIT NONE
INTEGER, PARAMETER :: N = 1000000
INTEGER :: I, Sayi, Sayac = 0
LOGICAL :: Asal
DO Sayi = 1, N
IF(Sayi<2) CYCLE ! Sayi = 1
IF(Sayi>2 .AND. MOD(Sayi,2)==0) CYCLE ! Sayi çift
Asal = .TRUE.
DO I = 2, Sayi-1
IF( MOD(Sayi,I) == 0 ) THEN
Asal = .FALSE.
EXIT
END IF
END DO
IF(Asal) THEN
Sayac = Sayac + 1
PRINT *,Sayi
END IF
END DO
PRINT *,"Toplam", Sayac, " adet."
END PROGRAM |
ÇIKTI
2
3
5
7
.
.
.
999959
999961
999979
999983
Toplam 78498 adet.
|
Asal sayıları bulmak için daha basit ve hızı çalışan Eratosthenes'in Kevgiri
(Sieve of Eratosthenes) algoritmasını kullanamak daha sağlıklıdır.
Daha fazla bilgi için:
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
Algoritma şöyledir:
- 2'den N'ye kadar sayıların listesini oluşturun.
- Listeden 2'nin katlarını (4, 6, 8, ...) çıkarıp yeni bir liste oluşturun.
- Yeni listedeki bir sonraki sayı asaldır.
- Listeden, bir önceki adımda bulunan sayının katlarını çıkarın.
- 3 ünçü ve 4 üncü adımları N sayısının kareköküne ulaşıncaya kadar tekrarlayın.
- Listede geriye kalan sayılar asaldır.
Örneğin: N = 25 olsun.
Liste: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
- 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
- 2'nin katlarını ele.
2 3 5 7 9 11 13 15 17 19 21 23 25
- 3'ün katlarını ele
2 3 5 7 11 13 17 19 23 25
- 5'in katlarını ele
2 3 5 7 11 13 17 19 23
- sqrt(25) = 5'e ulaşıldı. Son listedeki sayılar asaldır.
Bu algoritmanın kotarılması aşağıdaki programda göstrilmişitir.
Program 17.6: N = 100,000'dan küçük asal sayılar.
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
|
PROGRAM Asal_Sayilar
!----------------------------------------------------
! 17prg06.f95
! Eratosthenes Algoritması ile N = 100,000 den
! küçük asal sayılar.
! Kaynak:
! http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
!----------------------------------------------------
IMPLICIT NONE
INTEGER, PARAMETER :: N = 1000000
INTEGER :: I, Sayi, SqrtSayi, Sayac = 0
LOGICAL :: Asal
DO Sayi = 1, N
IF(Sayi<2) CYCLE ! Sayi = 1
IF(Sayi>2 .AND. MOD(Sayi,2)==0) CYCLE ! Sayi çift
Asal = .TRUE.
SqrtSayi = SQRT( REAL(Sayi) )
DO I =3, SqrtSayi, 2
IF( MOD(Sayi,I) == 0 ) THEN
Asal = .FALSE.
EXIT
END IF
END DO
IF(Asal) THEN
Sayac = Sayac + 1
PRINT *,Sayi
END IF
END DO
PRINT *,"Toplam", Sayac, " adet."
END PROGRAM |
ÇIKTI
2
3
5
7
.
.
.
999959
999961
999979
999983
Toplam 78498 adet.
|
NOT
Bu iki algoritma, Pentium 4 (3.7 GHz) işlemciye sahip bir bilgisayarda
çalıştırılmıştır. Program çalışma süreleri
yalın algoritma için yaklaşık 210 saniye ve
Eratosthenes'in Kevgiri için yaklaşık 25 saniye
olarak bulunmuştur. Dikkat edilirse Eratosthenes algoritması en az 8 kat daha hızlı çalışmaktadır.
|
|