2017-07-18 1 views
1

(リテラル定数)の末尾に必ずD(たとえば、1.234D+00)を指定する必要がありますか?倍精度マジックナンバーで作業するときのベストプラクティス

+0

魔法使いは何を意味していますか?例? – agentp

+0

@agentp、編集中のリンクをご覧ください。 –

+2

あなたは単にリテラル定数を意味すると思います。単精度表現が倍精度表現と同じであることが分かっている場合、 'D'は厳密には必要ありません。例えば、整数。 – agentp

答えて

7

短い回答:はい、そうです。

長い回答:特に指定がない限り、実際のリテラルは単精度です。倍精度変数に単精度リテラルを代入すると、精度が低下します。つまり、単精度リテラルは最初に単精度として評価され、より高精度の変数に割り当てられます。私は他の部屋からF2003ハンドブックを検索するのは面倒ですが、1対2の割り当てでは重要度の低い仮数ビットをゼロに設定すると思われます。それかそれともベンダーに任せられているのか。

にかかわらず、ここにあなたがリテラルと変数間の精度を混ぜるときに何が起こるかのデモが(0.1が2進浮動小数点にきれいに保存することができないことに注意してください)です。

!> Demonstrate the effects of D and E suffixes on precision of literals 
program whatkind 
    use iso_fortran_env, only: output_unit, REAL32, REAL64 
    implicit none 

    real (kind=REAL64) :: dtest 

10 format('Literal ', A, ' is of kind ', I2) 
20 format(/, A) 
30 format(/, 'Value stored in ', A, ' precision generated with ', A, & 
      ' precision literals:') 
40 format('Literal is ', A) 

    continue 

    write(output_unit, 10) '1.0', kind(1.0) 
    write(output_unit, 10) '1.0E0', kind(1.0E0) 
    write(output_unit, 10) '1.0D0', kind(1.0D0) 
    write(output_unit, 10) '1.0_REAL32', kind(1.0_REAL32) 
    write(output_unit, 10) '1.0_REAL64', kind(1.0_REAL64) 

    write(output_unit, 20) 'Raw tenths tests:' 

    dtest = 0.1 
    write(output_unit, 30) 'double', 'single' 
    write(output_unit, 40) '0.1' 
    write(output_unit, *) dtest 

    dtest = 0.1D0 
    write(output_unit, 30) 'double', 'double' 
    write(output_unit, 40) '0.1D0' 
    write(output_unit, *) dtest 

    dtest = 1.0/10.0 
    write(output_unit, 30) 'double', 'single' 
    write(output_unit, 40) '0.1' 
    write(output_unit, 40) '1.0/10.0' 
    write(output_unit, *) dtest 

    dtest = 1.0_REAL64/10.0_REAL64 
    write(output_unit, 30) 'double', 'double' 
    write(output_unit, 40) '1.0_REAL64/10.0_REAL64' 
    write(output_unit, *) dtest 

    dtest = 1.0_REAL32/10.0_REAL32 
    write(output_unit, 30) 'double', 'single' 
    write(output_unit, 40) '1.0_REAL32/10.0_REAL32' 
    write(output_unit, *) dtest 

    dtest = 1.0_REAL64/10.0_REAL32 
    write(output_unit, 30) 'double', 'mixed' 
    write(output_unit, 40) '1.0_REAL64/10.0_REAL32' 
    write(output_unit, *) dtest 

    dtest = 1.0_REAL32/10.0_REAL64 
    write(output_unit, 30) 'double', 'mixed' 
    write(output_unit, 40) '1.0_REAL32/10.0_REAL64' 
    write(output_unit, *) dtest 

end program whatkind 

この結果は次のとおりです。

Literal 1.0 is of kind 4 
Literal 1.0E0 is of kind 4 
Literal 1.0D0 is of kind 8 
Literal 1.0_REAL32 is of kind 4 
Literal 1.0_REAL64 is of kind 8 

Raw tenths tests: 

Value stored in double precision generated with single precision literals: 
Literal is 0.1 
    0.10000000149011612  

Value stored in double precision generated with double precision literals: 
Literal is 0.1D0 
    0.10000000000000001  

Value stored in double precision generated with single precision literals: 
Literal is 0.1 
Literal is 1.0/10.0 
    0.10000000149011612  

Value stored in double precision generated with double precision literals: 
Literal is 1.0_REAL64/10.0_REAL64 
    0.10000000000000001  

Value stored in double precision generated with single precision literals: 
Literal is 1.0_REAL32/10.0_REAL32 
    0.10000000149011612  

Value stored in double precision generated with mixed precision literals: 
Literal is 1.0_REAL64/10.0_REAL32 
    0.10000000000000001  

Value stored in double precision generated with mixed precision literals: 
Literal is 1.0_REAL32/10.0_REAL64 
    0.10000000000000001 

すべてのリテラルが単精度(明示精度が設定されていないものも含む)の場合、倍精度変数には重要度「ノイズ」が格納されています。

複雑なリテラルの操作は、操作が実行される前にすべてのリテラルがより高い精度に昇格するように見えることは興味深いことがわかりました。より多くの言語スペックを持つ人がそれを説明できるかもしれません。

私の助言:疑問があるときは、明示してください。それはより安全で、余分なキーストロークの価値があると私は思う。

+0

偉大な答えは、ありがとう。ほとんどのコンパイラは、混在した精度のインスタンスを捕捉するのには優れていますが、この場合、すべてのIsが点滅し、Tsが交差していることを確認するためにプログラマに委ねられていると思います。 –

+1

また、 'USINET、INTRINSIC :: ISO_Fortran_env、dp => REAL64'、' 1.234_dp'のように、 'KIND'パラメータを使って単精度リテラルをキャストすることがあります。いくつかのケースで見るのがよかったかもしれません。 –

+0

私の練習はWP = kind(1.0D0)として '作業精度'を定義することですが、私はWPをISO_Fortran_envの定数にエイリアス化する方法が気に入っています:) – arclight