2013-05-04 62 views
4

我有以下的Fortran代碼:數值精度Fortran 95中:

Program Strange 
    Real(Kind=8)::Pi1=3.1415926535897932384626433832795028841971693993751058209; 
    Real(Kind=8)::Pi2=3.1415926535897932384626433832795028841971693993751058209_8; 

    Print*, "Pi1=", Pi1; 
    Print*, "Pi2=", Pi2; 

End Program Strange 

我與gfortran編譯,並且輸出爲:

Pi1= 3.1415927410125732  
Pi2= 3.1415926535897931 

當然,第二個是正確的,而應此是這樣嗎?看起來Pi1正在作爲一個單精度數輸入到存儲器中,然後放入一個雙精度內存插槽。但這對我來說似乎是一個錯誤。我對麼?

回答

8

我知道一點Fortran! @ Dougal的答案是正確的,儘管他引用的片段並不是這樣,將字母d嵌入真正的字面常量並不是必需的(因爲Fortran 90),事實上許多Fortran程序員現在認爲這種方法是過時的。這段代碼在建議使用3.1415926535d+0爲pi初始化一個64位浮點值時也存在誤導,它沒有將足夠的數字設置爲正確的值。

聲明:

Real(Kind=8)::Pi1=3.1415926535897932384626433832795028841971693993751058209 

定義Pi1是有種8.真正的變量但是字面真正價值3.1415926535897932384626433832795028841971693993751058209是,默認的那種真正的價值,最有可能是一個4字節實在大多數當前編譯器上。這似乎解釋了您的輸出,但請檢查您的文檔。

另一方面,字面實際值Pi2=3.1415926535897932384626433832795028841971693993751058209_8通過類型說明的後綴聲明爲kind = 8,它與它被分配給的變量的類型相同。

另外三個要點:

1)不要落入認爲kind=8意味着同樣的事情64-bit floating-point numberdouble的陷阱。對於許多編譯器來說,它並不是。有關數字在Fortran實現之間不可移植。根據標準,它們是任意的正整數。更好的是,使用現代編譯器,將使用來自本質模塊iso_fortran_env的預定常數,例如,

use, intrinsic :: iso_fortran_env 
... 
real(real64) :: pi = 3.14159265358979323846264338_real64 

還有其他的便攜式方法來設定使用函數變量種如selected_real_kind

2)由於pi值是不可能的程序執行過程中改變你可能不在乎,使其參數因此:

real(real64), parameter :: pi = 3.14159265358979323846264338_real64 

3)這是沒有必要(或通常)至使用';'結尾的Fortran語句除非你想在源文件的同一行上有多個語句。

+0

一個非常清晰和詳細的答案。我非常感謝。 – user14717 2013-05-04 18:38:11

3

我真的不知道Fortran語言,但this page說:

字母「d」必須嵌入文字,否則,編譯器的預處理器將圓其關閉是一個單精度文字。例如,3.1415926535將被讀取爲3.141593,而3.1415926535d + 0將被存儲並且所有數字保持不變。雙精度數字的字母「d」與單精度數字的「e」意思相同。

所以看起來你的猜測是正確的。