回 帖 发 新 帖 刷新版面

主题:为什么输出值有很大跳跃?

program lsspline  

  implicit none

  integer(4), parameter :: ni=65

  real(8) :: xi(ni),yi(ni+2)

 pi = acos(-1.)

 do i=1,ni
   xi(i) = 1.*float(2*i-ni-1)/float(ni-1)
  enddo

yi(:) = 0.
    do i=1,ni
      yi(i) =  cos(pi*xi(i))           
    enddo


OPEN(400,file="dire_1d.dat")
      do i=1,ni                  
        WRITE(400,'(I2,2x,D16.8)')i,yi(i)
      end do
CLOSE(400)

end

回复列表 (共5个回复)

沙发

说实话,看到这样的程序,我首先想到的是该编程者是否有浮点数的相关知识;若是其为科研工作者,我就怀疑其算出来的结果是否可靠,进一步,能得出他论文上的结论吗?在浩如烟海的科研论文中,到底有多少是由这种不规范的计算程序所得到的“结论”,特别是目前场论中格点规范等领域,研究者的数值功底真的“够”吗?

    上述感慨对事不对人!
    对楼主,我想您应该首先规范浮点数据的书写,既然 real(8) :: xi(ni),yi(ni+2)
这一句 xi(i) = 1.*float(2*i-ni-1)/float(ni-1)
就有不妥之处,不要让编译器反复为你进行内部转换,不仅精度丢失,而且影响效率。
就我个人而言,我听不喜欢看到程序中出现类似
pi = acos(-1.)
语句的,何不直接将 Pi 的数值贴上来呢,程序算一个 acos 也不容易的,你可以去看看编译器一般是如何计算 acos 的。

修改后的程序如下:

subroutine ABC()
  implicit none
  
  integer, parameter :: ni = 65
  integer:: i   ! for loop
  real :: xi(ni), yi(ni + 2)
  real, save ::  pi = 3.14159265358979323846264E0

  do i = 1, ni, 1
    xi(i) = real(2 * i - ni - 1) / real(ni - 1)
  end do

  yi = 0.0
  do i = 1, ni, 1
    yi(i) =  cos(pi * xi(i)) 
    write(*, '(i2, 2x, E16.8)') i, yi(i)              
  end do

  return
end subroutine

我不知道您所谓的跳跃是什么?

板凳

pi = acos(-1.)

这样的语句一般编译器会算出 acos 直接作为立即数给 Pi。

运行时不会再计算,编译器这点优化能力还是有的

3 楼

嗯,這就是FORTRAN把這些東東都做為關鍵字的原因,換成用C++的話,就得用模板元的方式來優化了:)

4 楼

1 -- 编译也是需要时间的,编译时就不需要计算 acos 吗?很多时候,编译花的时间往往比运行花的时间更多,因为需要不断地修改、调试。
2 -- 除了极个别的“文字”, Fortran 没有关键字。

5 楼

……

我来回复

您尚未登录,请登录后再回复。点此登录或注册