2017-10-16 53 views
1

我剛剛得到一個快速問題,這個問題是由我在Fortran中獲取數字的平方根時得到的一個觀察結果產生的。下面的兩個語句比較sqrt(x)和x **(1./2。)之間的比較

wp = selected_real_kind(15, 307) 
    somevar = sqrt(3.0) 
    somevar2 = (3.0_wp)**(1.0/2.0) 

我發現somevar = 1.7320507764816284和somevar2 = 1.7320508075688772。根據https://apod.nasa.gov/htmltest/gifcity/sqrt3.1mil,似乎somevar2是更正確的答案。我的問題是如果聲明

squareroot = real(x,wp) ** (1.0/2.0) 

將始終導致一個數字的平方根更正確的值?

如果是這樣,那麼這與sqrt()函數默認返回單個精度變量的事實有關,或者這是與正在使用的編譯器相關的問題?

+0

nitpicker還希望在分數'(1.0/2.0)'中看到'_wp'。 –

回答

5

您在此處引用的sqrt通用本徵函數。該泛型接受任何實參或複合參數,並返回與參數類型和種類相同的結果。

在這種情況下,參數3.0是默認類型的實數(常量),因此結果也是實際的默認類型。另一方面,表達式(3.0_wp)**(1.0/2.0)是真實的,具有種類參數wp。這很可能是真實的,比其他真實的更精確。

如果你寫sqrt(3.0_wp)那麼這兩個表達式將是同一類型的,我期望這兩個值更加接近。

更一般地說,我不希望第二個表達式總是給出更準確的結果。

+0

sqrt(3_wp)應在大多數目標上使用IEEE精確指令來實現,或者可以在編譯時使用高精度庫進行計算,具體取決於您的編譯器。 – tim18

+0

@ tim18你準確的意思是什麼?這兩個表達式都可以在編譯時完成,但應遵循與運行時相同的規則。 –

3

讓我們分析一下這裏的代碼。這與已經給出的評論和答案一致,但我覺得仍然有一點可以解決的神祕感。

somevar = sqrt(3.0) 

這裏,3.0是將被存儲爲默認精度恆定(可能32位浮點值。即默認與gfortran反正)。因此sqrt將計算出該精確度的平方根。

對於somevar2,基數定義爲精度wp,但指數不是。

somevar2 = (3.0_wp)**(1.0/2.0) 

這與1.0/2.0正好存儲在二進制表示沒有影響。您可以通過比較兩個精度來檢查:

program test 
    implicit none 
    integer, parameter :: wp = selected_real_kind(15, 307) 
    real :: default_prec_half 
    real(kind=wp) :: wp_prec_half 

    default_prec_half = 1.0/2.0 
    wp_prec_half = 1.0_wp/2.0_wp 

    write(*,*) default_prec_half, wp_prec_half, default_prec_half-wp_prec_half 

end program test 

差值的輸出恰好爲0。

爲了說明,我用與NumPy的輸入程序來檢查斷言:

import numpy as np 
sqrt_3_32 = np.sqrt(3, dtype=np.float32) 
sqrt_3_64 = np.sqrt(3, dtype=np.float64) 
print(sqrt_3_32, sqrt_3_64) 

使用這兩種結果,我檢查的somevarsomevar2精度:

In [67]: somevar = 1.7320507764816284 

In [68]: somevar2 = 1.7320508075688772 

In [69]: somevar-sqrt_3_64 
Out[69]: -3.1087248775207854e-08 

In [70]: somevar-sqrt_3_32 
Out[70]: 0.0 

In [72]: somevar2-sqrt_3_64 
Out[72]: 0.0 

In [73]: somevar2-sqrt_3_32 
Out[73]: 3.1087248775207854e-08 

什麼出來的這是:

  1. somevar是3的平方根達到默認精度,並具有與32位NumPy計算的3的平方根相同的值。
  2. somevar2是3的平方根,直到wp的準確度與64位NumPy計算機的平方根相同。

注:我可以做比較,因爲我的平臺上的精度相匹配。雖然這是一般的情況下,我提供了比較的說明,你應該選擇適合你的問題的準確性,並在你的程序中一致地使用它。有關一般指南的浮點數,請參閱fortran90.org段落。

相關問題