5

異なるコンパイラを使用し、場合によっては異なるコンピューターを使用して、浮動小数点演算で同じ結果を得るにはどうすればよいですか?

これはp.f90です

program fl
implicit none
real(kind=8) :: a

a=9d0/10d0
write(*,*) a

end program

gfortran -op p.f90 を使用すると、 0.90000000000000002 が得られます

ifort -g -op p.f90 を使用すると、 0.900000000000000 が得られます

一貫性を達成する方法はありますか?小さなものが増殖して大きくなる。

よろしくアレッサンドロ

4

3 に答える 3

8

以下で浮動小数点演算に目を向けますが、最初にあなたの誤解に対処させてください。write ステートメントでリスト指定の書式設定を使用するということは、変数を書き出すためにコンパイラによって選択された書式が、コンパイラの選択であることを意味します。言語標準では義務付けられていません。2 番目*の in を使用するwrite(*,*)と、変数の値を必要に応じて書き出すようにコンパイラに指示します。したがって、あなたが持っているのは、算術に何か問題があるという証拠ではなく、 と の間に違いがあるという証拠gfortranですifort。あなたの書き込みステートメントを次のように変更すると

write(*,'(f21.18)') a

次に、Intel Fortran プログラムが次のように記述します。

0.900000000000000022

コンソールに。

SO には、浮動小数点演算の詳細に慣れていないことから生じる質問が散らばっているので、論文を書くつもりはありません。あなたの質問に関連するいくつかの観察だけです。

IEEE-754 の 64 ビット浮動小数点数 (これはおそらく宣言で得られるものですreal(kind=8)) は、約 16 桁の有用な情報しか提供しません。実際には、それらは 2 進数であり、ある基数と別の基数の桁数の間に簡単な対応がないため、実際には 10 進数で 15.95 桁であり、多くのユーザーはこれを切り捨てて、浮動小数点の 15 番目の有効数字の後に何も見ません。ポイント番号の 10 進数表現。ifortそのため、との両方gfortranが末尾2の s で誤解を招いています。

IEEE-754 では、fp 数値の形式だけでなく、丸めと算術演算の規則もいくつか定義されています。これらの算術演算 (平方根も指定されていると思います) のみを使用し、丸めモードと丸め操作に注意して慎重に作成されたプログラムは、2 つの異なるプロセッサで同じ結果を生成するはずです。もちろん、基本的な算術演算に限定された有用な数値プログラムは多くありません。

2003 年の標準 Fortran には、組み込みモジュールと呼ばれるモジュールが含まれており、ieee_arithmeticこれにより、プログラマーは、それが実行されているハードウェアの基礎となる IEEE-754 機能に直接アクセスできますが、ハードウェアがそのような機能を備えている必要はないことに注意してください。ieee_arithmeticと呼ばれる別の組み込みモジュールを使用するとieee_exceptions、ハードウェアが必要なサポートを提供する場合、 と の両方でコンパイルし、実行するとすべての fp 番号の最後のビットに同じ結果を生成するプログラムを作成できるはずgfortranですifort

また、使用しているコンパイラの最適化オプションと数値演算オプションに慣れる必要があります。ほとんどのコンパイラには、意味のあるオプションがありますsacrifice IEEE compliance for speedifort私はそれだと思いますfp-model)。一般に、操作を IEEE-754 に準拠させると、プログラムが遅くなります。

于 2012-10-30T10:11:56.230 に答える
1

それはいけません。

What Every Computer Scientist Should Know About Floating-Point ArithmeticのSystems Aspectsを参照してください。

于 2012-10-30T09:19:08.400 に答える
0

アリとして: できません。

結果を異なるコンパイラやアーキテクチャと比較できないことは、FORTRAN コンパイラのよく知られた問題です。それが不可能である主な理由は、FORTRAN コミュニティの設計上の決定と関係があります。コンピューターは、実行順序を変更し、速度を最適化するために内部コンピューターの特殊機能を使用する可能性があります。浮動小数点演算は分配的ではない [ x(y+z) != xy + xz ] ため、結果は実行順序に依存します。

例えば

1E308 (最大) + (1E308 - 2E308) ~= 0E308

(1E308 (最大) + 1E308) - 2E308 == 無限大

あなたは立ち往生しています。一部のコンパイラは、たとえば、「通常」とは異なる結果をもたらす多項式の計算に Fused 乗加算を使用しますが、これはまったく許可されています。

あなたは立ち往生しています。ごめん。

于 2012-11-01T12:53:39.253 に答える