什麼是初始化複雜數組的快速而準確的方法?是否有以下任何差異:將複雜數組初始化爲零的正確方法
complex(real64) :: x(2,2)
x = 0
x = 0d0
x = (0d0,0d0)
它們是否相同,我可以假設我在每個編譯器上得到相同的結果嗎?標準是否對此有任何說明?問題是特別是關於初始化爲零,而不是任何其他數字。
什麼是初始化複雜數組的快速而準確的方法?是否有以下任何差異:將複雜數組初始化爲零的正確方法
complex(real64) :: x(2,2)
x = 0
x = 0d0
x = (0d0,0d0)
它們是否相同,我可以假設我在每個編譯器上得到相同的結果嗎?標準是否對此有任何說明?問題是特別是關於初始化爲零,而不是任何其他數字。
在談到真正的答案之前,請注意術語。在Fortran中你在這裏不是初始化而是賦值。這是兩件不同的事情。是的,很清楚這裏是什麼意思,但也許很好意識到這個區別。
像x=0
這樣的行是內在賦值語句。 =
的左邊是變量,右邊是表達式。對於這些問題中的每一個,有兩個考慮因素:
如a related answer所述,當可變和表達類型或類型參數不同(但型貼合如在這種情況下)的表達轉換爲變量的類型和類型參數。
前兩個分配肯定涉及類型轉換:0
是一個整數,而0d0
是一個(雙精度)實數。雖然(0d0, 0d0)
是一個複雜的 - 所以沒有類型轉換 - 這將是別樣的,除非double precision
相同real(real64)
。
因此,至少前兩個我們已經轉換像相當於
x = CMPLX(0, KIND=real64)
x = CMPLX(0d0, KIND=real64)
和第三也許
x = CMPLX((0d0, 0d0), KIND=real64)
隨着
x = (0._real64, 0._real64)
我們可以肯定的變量和表達式的種類是相同的。
只要CMPLX(0, KIND=real64)
具有相同的值(0._real64, 0._real64)
可以肯定的是,分配x=0
(現在,標量x
)具有作爲x=(0._real64, 0._real64)
同樣的效果。這是Fortran標準的要求。
零是在它出現在每一個模型數集的特殊情況有所的,但每當一個(數學)數使用可以在所有三個被精確表示的效果將是相同的。同樣,
x = 3.14_real64
和
x = (3.14_real64, 0._real64)
是等價的。
但值得注意的是,有些選項的編譯器可能會提供有關隱式轉換的警告。即使數值相等,這也是一個不同之處。
即將到來的數組/標量方面:表達式被視爲與每個元素等於該標量值的變量具有相同形狀的數組。
總結:這三個任務中的每一個都具有相同的Fortran效果。在作業x
之後是給定形狀的陣列,每個元素具有複數值(0._real64, 0._real64)
。
現在,這並不是說不會有什麼令人興奮的事情發生在低級別的可能性,並且零設置可能是一個特殊情況。但那是你和你的編譯器(和系統)之間的事情。
謝謝,的確,我的意思是按照Fortran術語進行分配。我可以從你的最後一段推斷出答案不是我的問題,或者你不確定嗎?我懷疑零轉換始終沒有失去準確性。如果它是像3.14這樣的事情,那麼所有這三項任務顯然都會有所不同。 –
零在某種程度上是一種特殊情況,因爲在三個表示「整數」,「雙精度」和「實數(real64)」中的每一箇中,該值都可以精確地表示(我想可能存在奇怪的異常)。其他小數量整數也將是,所以這是「特殊」的限制。 '3.14'可能是一個不好的例子,因爲它不是整數,但是'x = 3.14'和'x = 3.14d0'可能會給出不同的結果,但是這取決於字面常量本身以及每種類型的近似值,而不是隨後的轉換爲複雜/真實(real64)'。 – francescalus
糾正我以前的評論:每個型號集中都明確存在零。哪些其他(數學)數字可以精確地表示在每個模型中取決於模型,但在實際水平1將是,但3.14不會。 – francescalus
由於你的「快速」,我問這個問題是關於編譯器是否可以做不同的事情(在運行時更快),但考慮到你對我的答案的評論,這可能實際上是寫作過程中的簡短/快速? – francescalus
是的,快意味着寫作簡潔。任何時候通過寫入'(0d0,0d0)'並避免隱式轉換可以被忽略。理想情況下,我會寫'x = 0',這可以節省我幾秒鐘的時間,並且可讀性好。但是,這是科學的代碼,我需要確定低層次上究竟發生了什麼。我目前只能訪問gfortran和ifort,對於他們來說,這些任務確實沒有任何區別。 –