組み込み関数 'CEILING'を使用しようとしていますが、丸め誤差により時々必要なものを得るのが難しくなります。丸め誤差の影響を受けずにCEILINGを使用
PROGRAM MAIN
IMPLICIT NONE
INTEGER, PARAMETER :: ppm_kind_double = KIND(1.0D0)
REAL(ppm_kind_double) :: before,after,dx
before = -0.112
dx = 0.008
after = CEILING(before/dx)
WRITE(*,*) before, dx, before/dx, after
END
そして、私は結果を得た:サンプルコードはちょうど非常に簡単です
コードで、私は「前」に与える値と 'dxはただのデモンストレーションのためです。たとえば/ dx = -13.5以前の場合は、CEILINGを使用して-13を取得します。しかし私が示す写真の場合、私は実際に-14を得たいと思っています。私はいくつかの引数を使用することを検討しました
しかし、それは単に美しくはありません。これを行うための良い方法はありますか?
アップデート:私はppm_kind_doubleの定数に変数を設定した場合、問題が発生しないことを知って驚いた
。この丸め誤差は、使用するマシンの丸め精度の桁数がppm_kind_doubleで定義されているもの以上の場合にのみ発生します。私は実際に私のプログラム(このデモコードではありません)をクラスタ上で実行していますが、マシンの精度についてはわかりません。だから多分問題の原因となるのはマシンの4倍の精度ですか?
私は倍精度に定数を設定した後:
before = -0.112_ppm_kind_double
dx = 0.008_ppm_kind_double
あなたは-14を望んで私を少し捨てました。 -0.112/0.008が正確に-14であることに気付くまでにはしばらく時間がかかりましたが、丸め誤差のために結果はやや多くなり、CEILINGはこの小さな誤差を増幅します。 – chw21
@ chw21、実際に私はあなたの以前のコメントを見て、それを見つけるのを待っていました。 :) – Ruizhi
ここでは精度が問題の一部ですが、リテラル定数は単精度のみであることには注意してください。 '-0.112'は' -0.112_ppm_kind_double'と書くべきでしょう。この変更によって根本的な問題は解決されません。 – IanH