Fortran 95将自己收集起来 [英] fortran 95 rounding up on it's own

查看:138
本文介绍了Fortran 95将自己收集起来的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我有插入排序算法: p>

 子程序insertion_sort_REAL4(array,array_len)
隐式无
!参数
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 out

Array =    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 out

Array =    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 statement write (*, *) 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆