2013-09-21 46 views
1

我決定學習fortran95語言(原因並不重要)。 不過作爲一名初學者,我遇到了一個奇怪的問題,我真的無法解釋,因此我需要幫助。fortran 95圍繞自己的

我有插入排序算法:

subroutine insertion_sort_REAL4(array, array_len) 
    implicit none 
!parameners 
    integer :: array_len 
    real (kind=4), dimension(array_len) :: array 
!variables 
    integer :: i,key,hole_pos 
    do i = 0,array_len 
     key = array(i) 
     hole_pos = i; 
     do while ((hole_pos > 0.0) .and. (key < array(hole_pos - 1))) 
     array(hole_pos) = array(hole_pos - 1) 
     hole_pos = hole_pos - 1 
     end do 
     array(hole_pos) = key 
    end do 
    return 
end 

還有主程序(節選):

real (kind = 4), dimension(3) :: x 
x(1) = 3.1 
x(2) = 4.3 
x(3) = 5.4 
write(*,*) 'Array = ',x 
call insertion_sort_REAL4(x,3) 
write(*,*) 'Array = ',x 

第一write語句打印出來

Array = 3.09999990  4.30000019  5.40000010 

爲什麼數字有輕微變化? fortran95默認不使用IEEE754標準嗎?

但是,讓我們說,我可以忍受輕微的變化;第二條write報表打印出來

Array = 3.00000000  4.00000000  5.00000000 

爲什麼數字被四捨五入? 這真的讓我感到困擾,格式化'寫'聲明沒有任何好處,谷歌搜索沒有真正幫助。我想在互聯網上沒有那麼多關於fortran的東西,因爲它是C.我是一個體面的C程序員,所以任何相似的東西都會被讚賞。 謝謝你的幫助!

+0

又是那一天。必須的鏈接:[每個計算機科學家應該知道的關於浮點算術](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – ppeterka

+0

在這種情況下,但他沒有做任何浮點運算。這些值將被精確地保留下來(如果不是意想不到的類型轉換)。 – agentp

回答

3

諸如「3.1」之類的十進制數字很可能在有限長度的二進制數中沒有確切的表示形式。源代碼語句x(1) = 3.1使計算機將該十進制數轉換爲二進制並存儲它。語句write (*, *) x(1)使計算機獲取此二進制值並將其轉換爲十進制。由於「3.1」不能用有限長二進制精確表示,所以轉換爲十進制並不能精確地恢復「3.1」。這解釋了「3.09999990」的輸出。這不是Fortran特有的,而是一般的有限精度浮點算法。

至於另一個問題,key在排序子程序中聲明爲整數,因此將實數四捨五入爲整數。當我編譯完全部編譯器警告程序後,gfortran通知我這件事。

如果你是gfortran,請嘗試下列編譯器選項:-O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -std=f2008 -pedantic -fbacktrace。你也會發現你的程序有一個下標錯誤。

+1

AH是的!謝謝!整數變量'鍵'是問題 - >我猜編譯器沒有通知就做了隱式轉換。順便說一句:什麼是下標錯誤?該程序編譯並正常工作... – Andro

+1

下標錯誤是程序引用不存在的數組元素時。例如,對於'array(1:3)',引用'array(0)'將是一個錯誤。如果你學習你的程序,你會發現這樣的問題。或者使用該選項進行編譯器的運行時下標檢查 - 使用此選項是Fortran與其他一些編譯語言相比的優勢之一。 –

+0

是的fortran隱式類型轉換,與C相同。 – agentp

1

對於第一部分:它確實使用IEEE754,這就是數字「改變」的原因。

What Every Computer Scientist Should Know About Floating-Point Arithmetic文章是一個必須閱讀以瞭解這是如何工作的,並有良好的IEEE754 calculators太...

所以3.1從來沒有準確3.1,但

3.0999999046325684 

首先。

對於第二部分:他們不圓但轉換爲整數,但我沒有把Fortran語言,所以我想的東西被聲明爲insertion_sort_REAL4常規INT,引起號碼被轉換爲整數。

+0

沒錯,就是這樣。感謝您的回答和鏈接。我應該讀一讀。 – Andro

+0

@Andrej啊,我現在看到M.S.Bs的回答,它解釋了一切。這篇文章讓人大開眼界。 – ppeterka