コードギャラリー

編集

このコードギャラリーは、さまざまなFortranの機能やパターン、ベストプラクティスを示すためのサンプルコード集です。

エラトステネスの篩

編集

このFortranのコードは、エラトステネスの篩を使用して指定された数以下の素数を見つけるプログラムです。以下にコードの各部分の解説を示します。

program SieveOfEratosthenes
    implicit none
    integer, parameter :: n = 100
    logical :: sieve(n + 1)
    integer :: i, j

    ! 初期化: 2以上の数は全てTrue
    sieve = .true.

    do i = 2, n
        if (sieve(i)) then
            do j = i * i, n, i
                sieve(j) = .false.
            end do
        end if
        if (i * i >= n) exit
    end do

    do i = 2, n
        if (sieve(i)) then
            print *, i, " "
        end if
    end do

end program SieveOfEratosthenes

このプログラムでは、次のように機能しています。

  • nは素数を探す範囲の上限を表す定数です。このプログラムでは100が設定されていますが、必要に応じて変更できます。
  • sieveは論理型の配列で、素数の判定結果を保持します。初期化時に全ての要素がTrueに設定されます。
  • do i = 2, nループは2からnまでの整数を処理します。sieve配列の要素がTrueの場合(素数の場合)、その数を出力し、その倍数を素数でないとマークします。

最大公約数と最小公倍数

編集
recursive integer function gcd2(m, n) result(ret)
    implicit none
    integer, intent(in) :: m, n

    ! GCDを計算する
    if (n == 0) then
        ret = m
    else
        ret = gcd2(n, mod(m, n))
    end if

end function gcd2

integer function lcm2(m, n) result(ret)
    implicit none
    integer, intent(in) :: m, n
    integer gcd2

    ! LCMを計算する
    ret = m * n / gcd2(m, n)
    
end function lcm2

program GCD_LCM
    implicit none
    integer gcd2, lcm2

    ! GCDとLCMを計算する
    print *, 'gcd2(30, 45) => ',  gcd2(30, 45)
    print *, 'gcd2(gcd2(30, 72), 12) => ', gcd2(gcd2(30, 72), 12)
    print *, 'lcm2(30, 72) => ', lcm2(30, 72)
    print *, 'lcm2(lcm2(30, 42), 72) => ', lcm2(lcm2(30, 42), 72)

end program GCD_LCM

このFortranのコードは、再帰的な関数gcd2lcm2を使用して最大公約数(GCD)と最小公倍数(LCM)を計算し、それらの結果を出力するプログラムです。

  • gcd2関数は再帰的に最大公約数(GCD)を計算します。与えられた2つの整数のGCDを求める際、ユークリッドの互除法を利用して計算します。引数が0になるまで再帰的に計算を行い、最終的な結果を返します。
  • lcm2関数は、与えられた2つの整数の最小公倍数(LCM)を計算します。LCMは最大公約数を利用して計算することができます。与えられた2つの整数の積を最大公約数で割ることでLCMを求めます。
  • program GCD_LCMは、gcd2lcm2を使って、指定された数のGCDとLCMを計算し、それらを出力します。このプログラムでは、print文を使って各関数の結果を表示しています。

Fortranのrecursiveキーワードは、自己参照的な(再帰的な)関数を定義する際に使用されます。このプログラムは与えられた数値のGCDとLCMを計算するFortranの例です。

二分法

編集

このFortranのコードは、二分法(Bisection Method)を使用して関数の根を見つける方法を示しています。以下にコードの各部分の説明を示します。

real(8) function f1(x)
    real(8), intent(in) :: x

    f1 = x - 1.0_8
end function f1

real(8) function f2(x)
    real(8), intent(in) :: x

    f2 = x*x - 1.0_8
end function f2

recursive real(8) function bisection(low, high, f) result(ret)
    real(8), intent(in) :: low, high
    real(8), external :: f
    real(8) :: x, fx

    x = (low + high) / 2.0_8
    fx = f(x)

    if (abs(fx) < 1.0d-10) then
        ret = x
    else
        if (fx < 0.0_8) then
            ret = bisection(x, high, f)
        else
            ret = bisection(low, x, f)
        end if
    end if
end function bisection

program BisectionMethod
    implicit none
    real(8) :: bisection
    real(8), external :: f1
    real(8), external :: f2

    print *, bisection(0.0_8, 3.0_8, f1)
    print *, bisection(0.0_8, 3.0_8, f2)

end program BisectionMethod
旧課程(-2012年度)高等学校数学B/数値計算とコンピューター#2分法の例を Fortran に移植しました。

このFortranコードは次のように動作します。

  • f1関数は f(x) = x - 1 の関数を表し、f2関数は f(x) = x^2 - 1 の関数を表します。それぞれの関数は与えられた引数 x に対して計算された結果を返します。
  • bisection関数は、与えられた範囲内で関数の根を見つけるために二分法を用いて計算します。この関数は、与えられた関数 f を用いて再帰的に範囲を半分に分割し、関数の根を探します。
  • program BisectionMethodでは、bisection関数を使用してそれぞれの関数の根を計算し、print文を使って結果を出力します。関数ポインタの代わりに、関数を外部から呼び出すための external 宣言が行われています。

脚註

編集