首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >定义必须声明为常量但在循环中更改的变量

定义必须声明为常量但在循环中更改的变量
EN

Stack Overflow用户
提问于 2014-08-28 02:09:24
回答 3查看 425关注 0票数 2

我正在测试函数selected_real_kind的值范围(-1:34 ),以确定它返回的kind参数以及使用此kind定义的变量使用的实际精度位数。我被如何定义下面的变量RP所困扰,因为转换变量xualpha的函数(例如real(x,RP))要求RP ( kind类型)为常量。

如果我将RP定义为parameter,即在顶部写integer, parameter :: RP,我必须立即初始化它,然后我显然不能更改它,因为它是一个parameter,所以这不起作用。

这就是我所拥有的:

代码语言:javascript
复制
program f1
  implicit none
  integer :: n,t  ! n used in selected_real_kind(n), t is precision (#bits)
  integer :: RP
  real :: x=1.5, u=1.0, alpha=1.0  ! will be reset using _RP below                                                                               

  print '(A2,A4,A4)', "n", "RP", "t"  ! header for values

  do n=-1,34
     RP = selected_real_kind(n)

     ! convert x,u,alpha to type RP.  These functions throw the error!                               
     x = real(x,RP)
     u = real(u,RP)
     alpha = real(alpha,RP)

     ! init precision test variables                                                                                                             
     x=1.5_RP
     u=1.0_RP
     alpha=1.0_RP

     ! reset precision value to zero before each test                                                                                            
     t = 0

     ! precision test                                                                                                                            
     do while(x>alpha)
        u = u/2.0_RP
        x = alpha+u
        t = t+1
     end do

     print '(I2 I4 I4)', n, RP, t
  end do

end program f1
EN

回答 3

Stack Overflow用户

发布于 2014-08-28 02:54:03

Fortran提供了许多内部函数来查询它所处理的数字的特征。有关digitsprecisionradix等函数,请参阅您的文档。所有这些(包括我没有提到但您的文档将列出的那些)都是通用的(足够)来处理编译器支持的所有数值类型的输入。

使用这些函数比尝试使用自己的函数更快。正如您正在发现的那样,编写自己的泛型例程并不是一件简单的事情,因为Fortran希望在编译时已知(或可知)种类选择器。您还将扩展您的Fortran知识。

您还可以在内部模块IEEE_ARITHMETIC中找到感兴趣的函数。

票数 1
EN

Stack Overflow用户

发布于 2014-08-28 04:46:50

下面是一个python示例,详细说明我的评论:

代码语言:javascript
复制
 fortrancode = """
       implicit none
       integer, parameter :: n=%i
       integer,parameter :: rp=selected_real_kind(n)      
       write(*,*)n,rp
       end
 """
 from subprocess import call
 for n in range(-1,33):
  f=open('test.f','w')
  f.write(fortrancode%(n))  ! <- n here gets string substituted
                            !for the '%i' in fortrancode
  f.close()
   ! optional check  call(['grep','n=','test.f'])
  call(['gfortran','test.f','-o','test.exe'])
  call(['./test.exe'])

python test.py

代码语言:javascript
复制
 -1 4
  0 4
  1 4
...
  7 8
...
 18 10
 19 -1
...
 32 -1
票数 1
EN

Stack Overflow用户

发布于 2014-08-28 04:58:51

类似于george's answer,但在fortran语言中。我们注意到,种类本质上是在编译时必须知道的东西。为此,我们询问编译器它可以为我们提供哪些类型,并为每种类型创建一小块要编译的代码。然后编译并运行它。最后一步肯定会因系统而异。

代码语言:javascript
复制
! Rather than looping over a range with SELECTED_REAL_KIND, just see which
! real kinds are available to the compiler.  We can later match up real kinds
! for a requested precision with those here.
  use, intrinsic :: iso_fortran_env, only : real_kinds
  implicit none

  integer output
  integer i

  open(newunit=output, file='gosh.f90', action='write', position='rewind')

! Here we could instead do n=-1, 34 etc.
  do i=1, SIZE(real_kinds)
     write(output, 1) real_kinds(i)
  end do

  write(output, '("end")')
  close(output)

! A compile/execute line - do whatever is required.
  call execute_command_line('compile gosh.f90 && ./a.out')

1 FORMAT ("block",/,"real(",I0,") x",/,"include 'domystuffz'"/,"end block")

end

其中"domystuffz“是包含所需分析的文件。与High Performance Mark's answer一样,一些内在的东西也很好,如果需要,可以用一些简单的代码替换include

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25534202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档