Fortran 95将自己收集起来 [英] fortran 95 rounding up on it's own
问题描述
我决定学习fortran95语言(原因并不重要)。
然而,作为初学者,我遇到了一个奇怪的问题,我真的无法解释,因此我需要帮助。
我有插入排序算法: p>
子程序insertion_sort_REAL4(array,array_len)
$ p $ b>
隐式无
!参数
integer :: array_len
real(kind = 4),dimension(array_len):: array
!变量
integer :: i,key,hole_pos
do i = 0,array_len
key = array(i)
hole_pos = i; ((hole_pos> 0.0)。和。(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
调用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程序员,所以任何相似的东西都会被赞赏。
感谢您的帮助!解决方案例如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 -Wsprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck = all -std = f2008 -pedantic -fbacktrace
。您还会发现您的程序有一个下标错误。I decided to learn the fortran95 language (reason why is not important). However being a beginner I ran into a weird problem I really can't explain, therefor I need help.
I have the insertion sort algorithm:
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
And there is the main program (excerpt):
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
The first
write
statement prints outArray = 3.09999990 4.30000019 5.40000010
Why have the numbers been slightly changed? Does fortran95 not use the IEEE754 standard by default?
But let's say I can live with the slight alteration; the second
write
statements prints outArray = 3.00000000 4.00000000 5.00000000
Why have the numbers been rounded up? It's really bugging me and formatting the 'write' statement isn't doing any good and the Google searches haven't really helped. I guess there is not that many things on the internet about fortran as it is of C. I am a decent C programmer so any parallels to it are appreciated. Thanks you for your help!
解决方案A decimal number such as "3.1" will likely not have an exact representation in a binary number of finite length. The source code statement
x(1) = 3.1
causes the computer to convert that decimal number into binary and store it. The statementwrite (*, *) x(1)
causes the computer to fetch this binary value and convert it to decimal. Because "3.1" could not be exactly represented in finite-length binary, the conversion to decimal does not precisely recover "3.1". This explains the output of "3.09999990". This is not Fortran specific, but general to finite precision floating point arithmetic.As to the other problem,
key
is declared integer in the sort subroutine and is thus rounding the reals to integers. When I compiled your program with full compiler warnings turned on, gfortran notified me of this.If you you gfortran, try the following compiler options:
-O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -std=f2008 -pedantic -fbacktrace
. You will also find that your program has a subscript error.这篇关于Fortran 95将自己收集起来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!