(リテラル定数)の末尾に必ずD
(たとえば、1.234D+00
)を指定する必要がありますか?倍精度マジックナンバーで作業するときのベストプラクティス
答えて
短い回答:はい、そうです。
長い回答:特に指定がない限り、実際のリテラルは単精度です。倍精度変数に単精度リテラルを代入すると、精度が低下します。つまり、単精度リテラルは最初に単精度として評価され、より高精度の変数に割り当てられます。私は他の部屋から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
すべてのリテラルが単精度(明示精度が設定されていないものも含む)の場合、倍精度変数には重要度「ノイズ」が格納されています。
複雑なリテラルの操作は、操作が実行される前にすべてのリテラルがより高い精度に昇格するように見えることは興味深いことがわかりました。より多くの言語スペックを持つ人がそれを説明できるかもしれません。
私の助言:疑問があるときは、明示してください。それはより安全で、余分なキーストロークの価値があると私は思う。
偉大な答えは、ありがとう。ほとんどのコンパイラは、混在した精度のインスタンスを捕捉するのには優れていますが、この場合、すべてのIsが点滅し、Tsが交差していることを確認するためにプログラマに委ねられていると思います。 –
また、 'USINET、INTRINSIC :: ISO_Fortran_env、dp => REAL64'、' 1.234_dp'のように、 'KIND'パラメータを使って単精度リテラルをキャストすることがあります。いくつかのケースで見るのがよかったかもしれません。 –
私の練習はWP = kind(1.0D0)として '作業精度'を定義することですが、私はWPをISO_Fortran_envの定数にエイリアス化する方法が気に入っています:) – arclight
- 1. C#の倍精度精度の損失、減算の倍数を加算するときの精度の低下
- 2. C++倍精度/精度
- 3. 倍精度とfmodでエラー
- 4. 4倍のCPU時間と倍精度
- 5. IEEEの単精度と倍精度で表される総数
- 6. 倍精度
- 7. Javaの倍精度
- 8. 条件付きでJavaが倍精度に倍精度化されない
- 9. SSIS倍精度prob
- 10. PHPUnitテスト倍精度
- 11. 倍精度のprintf丸め動作
- 12. 精度で倍精度を出力する
- 13. C - IEEE 754の倍精度と単精度の格納方法
- 14. 単精度、倍精度、および精度
- 15. 倍精度を追加する際の精度の低下
- 16. Javaの単精度/倍精度は何ですか?
- 17. 倍精度:大きな数の乗算
- 18. NSNumberFormatter iOSの大きな倍精度値
- 19. OpenCL倍精度が動作しない
- 20. 倍精度を返す0
- 21. 倍精度の拡張
- 22. QString :: toDouble()が誤った精度で倍精度を返す
- 23. LinuxとMacの4倍精度
- 24. ここNSDateと倍精度の問題
- 25. スウィフトで倍精度以上の精度を実現
- 26. 単一精度でのCUDA帯域幅と倍精度での帯域幅
- 27. 倍精度乱数列
- 28. iPhone/iPad倍精度数学
- 29. 機能CORR(倍精度、倍精度)が存在しない - のPostgresSQL
- 30. C#DateTime:倍精度浮動小数点型時間の倍精度化
魔法使いは何を意味していますか?例? – agentp
@agentp、編集中のリンクをご覧ください。 –
あなたは単にリテラル定数を意味すると思います。単精度表現が倍精度表現と同じであることが分かっている場合、 'D'は厳密には必要ありません。例えば、整数。 – agentp