1

我决定学习 fortran95 语言(原因并不重要)。然而,作为一个初学者,我遇到了一个我真的无法解释的奇怪问题,因此我需要帮助。

我有插入排序算法:

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 程序员,所以任何与它的相似之处都值得赞赏。谢谢你的帮助!

4

2 回答 2

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. 你还会发现你的程序有一个下标错误。

于 2013-09-21T20:05:26.447 回答
1

对于第一部分:它确实使用IEEE754,这就是数字“更改”的原因。

What Every Computer Scientist Should Know About Floating-Point Arithmetic文章是了解其工作原理的必读之物,也有很好的IEEE754 计算器...

所以3.1从来都不是3.1,但是

3.0999999046325684

首先。

至于第二部分:它们没有四舍五入而是转换为整数,但我没有进入 Fortran,所以我猜在insertion_sort_REAL4例程中将某些东西声明为 int,这会导致数字转换为整数。

于 2013-09-21T20:07:58.817 回答