Temel Yönleriyle Fortran 90 / 95 / 2003

  Temel Konular
* Ö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

  İleri Uygulamalar
* - - -
* 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

  Seçilmiş Örnekler
* Sayılar Kuramı
* Analiz
* Lineer Cebir

  Fortran 90/95 Derleyicileri
* Salford (silversoft FTN95)
* G95
* GFORTRAN

  Dış Bağlantılar
* programlama.com
* Fortran (wikipedia)

* fortran.gantep.edu.tr
* g95.org
* Hot scripts

  İletişim
* 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

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

  1. 2'den N'ye kadar sayıların listesini oluşturun.
  2. Listeden 2'nin katlarını (4, 6, 8, ...) çıkarıp yeni bir liste oluşturun.
  3. Yeni listedeki bir sonraki sayı asaldır.
  4. Listeden, bir önceki adımda bulunan sayının katlarını çıkarın.
  5. 3 ünçü ve 4 üncü adımları N sayısının kareköküne ulaşıncaya kadar tekrarlayın.
  6. 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.



Powered by PHP