2016-10-29 1 views
1

なぜこのfortranプログラムはゼロのみを生成するのですか?私がそれを印刷すると、私はどこでも-0.00000を得ます!私は何を間違えたのですか? matlabで完全に動作します。正直ではない理由は何もわかりません!ゼロを生成する単純なプログラム、バグ?

これは、それを混乱させる部分のようです。 xを十進数と同じにすると、それは機能します。

program main 


implicit none 
    integer iMax, jMax 
    double precision, dimension(:,:), allocatable :: T 

double precision x, dx,f,L2old,L2norm,y 

integer i, j,n,bc 

n=10 

allocate(T(1:n+2, 1:n+2)) 

T=0.0d0 

do i=2,n+1 
do j=2,n+1 

x=(j+1)*1/24 
y=(i+1)*1/24 


T(i,j)= -18*(x**2+y**2)**2 

Write(*,*)'T(',i,'',j,'', T(i,j) 

end do 
end do 

Write(*,*)'T(1,1)',T(1,1) 


end program main 
+2

につながる私は*すべての* Fortranのを覚えていないが、 '* 1/24'は、整数の除算のような非常に多くを探します。 –

答えて

3
x=(j+1)*1/24 

1/24あなたが浮動小数点オペランドのうちの少なくとも一方を行うことで、浮動小数点除算を強制することができなければならない0に切り捨て整数除算であり、 例えば

x=(j+1)*1.0/24.0 
1

ジム・ルイスが指摘したように、OPの質問に対する答えは、実際には整数の除算でした。

浮動小数点数をどのように書き留めておくべきかを指摘することが重要です。 OPのプログラムが示すように、xDOUBLE PRECISIONであった。そして、正しい結果がここでの違いは、今あなたがxが宣言されたように部門が同じ精度で起こっていることを確認していることである

x=(j+1)*1.0D0/24.0D0 

でなければなりません。以下のプログラムに

は問題::

program test 
WRITE(*,'(A43)') "0.0416666666666666666666666666666666..." 
WRITE(*,'(F40.34)') 1/24 
WRITE(*,'(F40.34)') 1.0/24.0 
WRITE(*,'(F40.34)') 1.0D0/24.0 
WRITE(*,'(F40.34)') 1.0D0/24.0D0 
end program test 

出力として

0.0416666666666666666666666666666666... 
0.0000000000000000000000000000000000 
0.0416666679084300994873046875000000 
0.0416666666666666643537020320309239 
0.0416666666666666643537020320309239 

あなたははっきりと違いを参照してください示しています。最初の行は数学的に正しい結果です。 2行目はゼロにつながる整数除算です。 3行目は、除算がREALと計算され、4行目と5行目がDOUBLE PRECISIONになる場合の出力を示しています。私のケースでは、REALは32ビット浮動小数点数を意味し、DOUBLE PRECISIONは64ビット版を意味することを考慮してください。 REALDOUBLE PRECISIONの精度と表現はコンパイラに依存し、the Standardでは定義されていません。 DOUBLE PRECISIONは、REALより高い精度が必要です。

4.4.2.3実数型

実数型は、数学的な実数を近似値を持っています。プロセッサは、実数型のデータの値の集合を定義する2つ以上の近似方法を提供しなければならない。そのような各メソッドは表現方法を持ち、種別型パラメータKINDの値によって特徴付けられます。近似法の種類の型パラメータは、組み込み関数KIND(13.7.89)によって返されます。

タイプキーワードREALは、種別型パラメータなしで使用される場合、デフォルト実際の種類に 実数型が指定され、種類の値が KIND(0.0)です。型指定子DOUBLE PRECISIONは倍精度の種類の実数 を指定します。種別値はKIND(0.0D0)です。倍精度実近似法 の小数精度は、デフォルトの実数法よりも大きくなければなりません。

これは実際にあなたがあなたの計算は32ビット、64ビットまたは128ビットの浮動小数点表現を使用して行われていることを確認したい場合は組み込みモジュールISO_FORTRAN_ENVで定義されている、あなたは正しいKIND値を使用することをお勧めします、ということを意味します。

13.8.2.21 REAL32、REAL64、及びREAL128

定数名前これらのデフォルトの整数のスカラーの値が ストレージREALタイプを指定する種別型パラメータのものでなければなりませんビットで表されるサイズは、それぞれ32,64、および128です。これらの定数のいずれかが の場合、プロセッサはそのサイズの複数の種類 をサポートしていますが、どの種類の値が提供されているかはプロセッサに依存します。 プロセッサが特定のサイズの種類をサポートしていない場合は、 という大きいサイズの種類をサポートしている場合はその定数 は-2に等しくなり、そうでない場合は-1になります。

だから、これは次のコード

PROGRAM main 
    USE iso_fortran_env, ONLY : DP => REAL64 
    IMPLICIT NONE 
    ... 
    REAL(DP) :: x 
    ... 
    x = (j+1)*1.0_DP/24.0_DP 
    ... 
END PROGRAM main 
関連する問題