web-dev-qa-db-ja.com

Fortran:整数* 4 vs整数(4)vs整数(kind = 4)

私はFortranを学ぼうとしていますが、多くの異なる定義が渡されているのを見て、それらが同じことを達成しようとしているのではないかと思っています。次の違いは何ですか?

  • _integer*4_
  • integer(4)
  • integer(kind=4)
54
Sam

Fortran> = 90での最良のアプローチは、組み込み関数を使用して必要な精度を指定することです。これにより、移植性と必要な精度の両方が保証されます。たとえば、少なくとも8桁の10進数をサポートする整数iおよび_my_int_を取得するには、次を使用できます。

_integer, parameter :: RegInt_K = selected_int_kind (8)
integer (kind=RegInt_K) :: i, my_int
_

_RegInt_K_(または選択した名前)をparameterとして定義すると、コード全体でシンボルとして使用できます。これにより、精度の変更も簡単になります。

通常、8桁または9桁の10進数を要求すると、4バイトの整数が取得されます。

_integer*4_は、古いFORTRANに戻って4バイト整数を指定する一般的な拡張機能です。ただし、この構文は標準のFortranではなく、標準のFortranでもありませんでした。

integer (4)またはinteger (RegInt_K)は、integer (kind=4)またはinteger (kind=RegInt_K)の短縮形です。 integer (4)は_integer*4_と同じではなく、移植性がありません-言語標準は種類の数値を指定していません。ほとんどのコンパイラは、4バイト整数に_kind=4_を使用します。これらのコンパイラでは、_integer*4_とinteger(4)は同じ整数型を提供しますが、例外があります。したがって、integer(4)は移植性がなく、避けるのが最善です。

実数に対するアプローチも同様です。

更新:必要な精度で数値型を指定するのではなく、使用する記憶域で数値型を指定する場合、Fortran 2008はメソッドを提供します。実数と整数は、_ISO_FORTRAN_ENV_モジュールをuseingした後のストレージのビット数で指定できます。たとえば、4バイト(32ビット)整数の場合:

_use ISO_FORTRAN_ENV
integer (int32) :: MyInt
_

Gfortranマニュアルには、「組み込みモジュール」の下にドキュメントがあります。

56
M. S. B.

種類が何であるかをもう1つ明示的に説明します。コンパイラには、さまざまな数値型のテーブルがあります。すべての整数型は、基本型の種類の種類とは異なります-integer。コンパイラに1バイト、2バイト、4バイト、8バイト、および16バイトのinteger(またはreal)の種類があるとします。表では、コンパイラはこの種類のそれぞれにインデックスを持っています-このインデックスは種類番号です。

多くのコンパイラはこの番号付けを選択します。

_kind number    number of bytes
1              1
2              2
4              4
8              8
16             16
_

ただし、他の番号を選択できます。明らかな可能性の1つは

_kind number    number of bytes
1              1
2              2
3              4
4              8
5              16
_

実際、このアプローチを選択するコンパイラ(少なくともg77とNAG)があります。これを変更するオプションもあります。したがって、kind番号は移植性がありませんinteger(kind=4)またはinteger(4)は、コンパイラーに応じて4バイト整数または8バイト整数を意味します。

_integer*4_は、常に4バイトを意味するという意味で移植可能です。しかし、一方で、それは決して標準の一部ではなかったため、ポータブルではありません。この表記を使用するプログラムは、有効なFortran 77、90、またはその他のFortranではありません。

種類番号の設定方法の正しいオプションについては、MSの回答をご覧ください。

同じ概念がrealデータ型にも当てはまります。 Fortran 90 kindパラメーター (mataapの答え)を参照してください。

25
Vladimir F

@ -SteveLionelが最近書いた この啓発的な記事 を参照し、これまでの他の回答にはない詳細をカバーしてみます。


  1. _integer*n_または_real*n_に示されている構文は、以前にコンパイラによって提供された一般的な拡張機能であり、異なるコンピューターアーキテクチャーでは、整数値と実際の値のメモリ内フォーマットの設計が異なり始めたときに、n保存されている値のバイト単位のサイズ。ただし、これらの値の範囲や精度については何も言われていません。たとえば、16ビット整数の異なる実装は、異なる範囲と制限値を提供できます。

レジスタサイズは8、12、16、30、32、36、48、60、または64ビットであり、一部のCDCマシンには1の補数整数があり(整数にマイナスゼロを許可します!)、PDP-11行にはいくつかの異なる浮動小数点がありますシリーズに応じたポイント形式、IBM 360/370には浮動小数点などの「16進正規化」がありました[...]多くのプログラマーは、この構文が標準Fortranであると考えていました(そして今日でも多くの人が考えている) ;そうではありません!


  1. Fortran 90が登場したとき、kindパラメーターが言語に追加され、組み込みの照会関数(特にkind、_selected_int_kind_および_selected_real_kind_だけでなく、precisiondigitsepsilon...など)プログラマーが数値型のprecisionとrangeの最小要件を指定するのを支援します(まだ、ストレージモデルまたはバイトに関する公式の言及はありません)。構文はinteger(kind=n)またはinteger(n)です。ここで、nは、コンパイラーがサポートする整数の種類に対応する定数値です。リテラル定数の場合、構文は_12_n_または_3.4e-2_n_です。

    このソリューションの利点は、Fortranが、型を選択するために使用される照会関数の結果以外のデータ型の実装の詳細について仮定を行わない(まだしない)ことでした。そのため、コードは言語やハードウェアではなく、解決される問題。落とし穴は、他の答えで述べたように、各コンパイラーが種類番号を選択できるため、integer(4)のようなマジックナンバーは移植性がないと仮定しています。


  1. また、Fortran 90にはdefault kindという概念がありました。これは、種類を指定しない場合に得られるものです。

デフォルトの種類は実装に依存していましたが、Fortran 2008までは、コンパイラは整数の種類1つと実際の種類2つだけをサポートする必要がありました。 (Fortran 2018でも同様ですが、少なくとも1つの整数の種類が18桁の10進数をサポートするという追加の要件があります。)種類指定子なしで定数リテラルを記述すると、デフォルトの種類が得られます。


  1. Fortran 2003と組み込みモジュール_ieee_arithmetic_を含めると、使用可能な場合、IEEE浮動小数点機能を備えた実数型を照会および選択できます。

HP(旧Compaq以前DEC)Alphaなど、IEEEおよびIEEE以外の浮動タイプの両方が利用可能なアーキテクチャがあります。この場合、組み込みモジュールIEEE_ARITHMETICからIEEE_SELECTED_REAL_KINDを使用して、IEEE浮動種類を取得できます。また、要件を満たすサポートされている種類がない場合はどうなりますか?その場合、組み込み関数は負の数を返し、(通常、コンテキストに応じて)コンパイル時エラーがトリガーされます。


  1. 最後に、Fortran 2003は_iso_fortran_env_組み込みモジュールをもたらしました。これには、コンパイラーが実装する型のstorage sizeを照会する関数があり、組み込み関数があります_numeric_storage_size_や_bit_size_など。 Fortran 2003リビジョンのもう1つの追加は_iso_c_binding_組み込みモジュールで、これはkindパラメーター値を提供して、ストレージ、精度、および範囲でCタイプとの互換性を保証します。

組み込みモジュールISO_C_BINDINGは、C_FLOATやC_INTなど、C型と相互運用可能なFortran型の定数を宣言します。 Cと相互運用可能な変数とインターフェイスを宣言する場合は、これらを使用します。


  1. 最後に、組み込みモジュール_iso_fortran_env_を拡張して名前付き定数_int8_、_int16_、_int32_ m _int64_を含む最近のFortran 2008標準について言及します。 _real32_、_real64_、および_real128_。これらの値は、指定されたビット数を占める整数の種類と実際の種類に対応します。落とし穴は、これらの定数が精度または範囲ではなく、ストレージサイズのみを保証することです。これがまさにあなたが望むものである場合にのみ使用してください。

私の見解では、これは古い* n拡張子よりも少し優れていますが、それは型がその多くのビットに適合することを伝えますが、それ以外のことは何もありません。例として、REAL128が128ビットで格納されているが、実際には古いx86浮動小数点スタックレジスタで使用される80ビットの「拡張精度」実数であるコンパイラがあります。これらを使用すると、ポータブル機能を使用していると思われるかもしれませんが、実際にはそうではなく、必要な機能がない場合に噛み付く可能性があります。

1