2013-09-21 48 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