我决定学习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程序员,所以任何与它相似的东西都值得赞赏。 谢谢你的帮助!
答案 0 :(得分:3)
诸如“3.1”之类的十进制数可能不具有有限长度的二进制数的精确表示。源代码语句x(1) = 3.1
使计算机将该十进制数转换为二进制数并存储它。语句write (*, *) x(1)
使计算机获取此二进制值并将其转换为十进制。因为“3.1”无法用有限长度的二进制文件精确表示,所以转换为十进制并不能精确地恢复“3.1”。这解释了“3.09999990”的输出。这不是Fortran特有的,而是一般的有限精度浮点运算。
至于另一个问题,key
在sort子例程中被声明为整数,因此将实数四舍五入为整数。当我编译你的程序时打开了完整的编译器警告,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 :(得分:1)
对于第一部分:它确实使用了IEEE754,这就是数字被“更改”的原因。
必须阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic文章,了解这是如何运作的,而且IEEE754 calculators也很好......
所以 3.1 从未完全 3.1 ,但
3.0999999046325684
首先。
至于第二部分:它们不是舍入 up 但是转换为整数,但我不是Fortran,所以我想某些东西被声明为int in insertion_sort_REAL4
例程,导致数字转换为整数。