意外的gfortran编译错误
最近,我开始学习fortran编程。我在youtube上看到了以下代码,没有任何错误,它是编译的。但是我有一些错误。 谢谢你的帮助意外的gfortran编译错误,fortran,Fortran,最近,我开始学习fortran编程。我在youtube上看到了以下代码,没有任何错误,它是编译的。但是我有一些错误。 谢谢你的帮助 program implicit none real, parameter :: pi=4*atan(1.0) integer, parameter :: n = 100 real :: dimension(1:n) :: x, y real :: a=0.0, b = 2*pi real :: increment integer :
program
implicit none
real, parameter :: pi=4*atan(1.0)
integer, parameter :: n = 100
real :: dimension(1:n) :: x, y
real :: a=0.0, b = 2*pi
real :: increment
integer :: i
increment = (b-a)/(real(n)-1)
x(1)=0.0
do i =2,n
x(i) = x(i-1) + increment
end do
y = sin(x)
print *, x(1:5)
print *, y(1:5)
end program
real::dimension(1:n)::x,y
是一个语法错误。用逗号替换第一个:
。您可能需要在程序语句中指定一个名称。行中还有混合模式算术
增量=(b-a)/(实(n)-1)
它可能会编译,甚至可能不会影响程序,但您不应该在任何编程语言中使用混合模式算法,因为它可能会导致奇怪的、难以发现的错误。应该是这样的:
increment=(b-a)/(real(n)-1.0)
以下是一个解决@High Performance Mark问题的工作示例的结果
host system = (redacted)
compiler version = GCC version 5.1.0
compiler options = -fPIC -mmacosx-version-min=10.9.4 -mtune=core2 -Og -Wall -Wextra -Wconversion -Wpedantic -fmax-errors=5
execution command = ./a.out
Compare mesh points
1.57017982 1.57080817 1.57143652
1.57016802 1.57079625 1.57142460
Compare function values at these mesh points
1622.04211 -84420.7344 -1562.01758
1591.57471 13245402.0 -1591.65527
在您发现的演示中有一个糟糕的编程实践:通过添加步数(+increment)而不是计数步数(k*increment),在网格中移动。这一问题很普遍,并且会带来严重后果()
为了在代码上演示,网格的大小增加到10K点。此外,样本函数从cos x
变为tan x
,我们检查了pi/2=1.57079633处奇点附近的点。虽然新手可能会发现网格值的差异微不足道,但函数值的差异却非常显著
(网格误差可以通过使用具有精确二进制表示形式(如2^(-13)=1/8192)的增量来减少。)
代码如下所示。编译命令是gfortran-Wall-Wextra-Wconversion-Og-pedantic-fmaxerrors=5 demo.f95
。run命令是/a.out
program demo
use iso_fortran_env
implicit none
real, parameter :: pi = acos ( -1.0 )
integer, parameter :: n = 10001
real, dimension ( 1 : n ) :: x, y, z
real :: a = 0.0, b = 2 * pi
real :: increment
integer :: k, quarter, status
character ( len = * ), parameter :: c_options = compiler_options( )
character ( len = * ), parameter :: c_version = compiler_version( )
character ( len = 255 ) :: host = " ", cmd = " "
! queries
call hostnm ( host, status )
call get_command ( cmd )
! write identifiers
write ( *, '( /, "host system = ", g0 )' ) trim ( host )
write ( *, '( "compiler version = ", g0 )' ) c_version
write ( *, '( "compiler options = ", g0 )' ) trim ( c_options )
write ( *, '( "execution command = ", g0, / )' ) trim ( cmd )
increment = ( b - a ) / ( n - 1 )
quarter = n / 4
! mesh accumulates errors
x ( 1 ) = 0.0
do k = 2, n
x ( k ) = x ( k - 1 ) + increment
end do
y = tan ( x )
print *, 'Compare mesh points'
print *, x ( quarter : quarter + 2 )
! better mesh
x ( 1 ) = 0.0
do k = 2, n
x ( k ) = ( k - 1 ) * increment
end do
z = tan ( x )
print *, x ( quarter : quarter + 2 )
print *, 'Compare function values at these mesh points'
print *, y ( quarter : quarter + 2 )
print *, z ( quarter : quarter + 2 )
end program demo
“一些错误”可以通过“一些解决方案”来解决。更具体一点。并且要具体说明您使用的是哪个版本的gfortran。我不相信对于这样简单的常量来说这是一个问题。编译器将以一种简单的方式进行转换。标准对混合模式算法进行了很好的定义,并且不应依赖于编译器-参见2008标准第7.1.5.1节和表7.2。这里额外的冗长是多余的,
(b-a)/(n-1)
产生预期的结果,因为a
和b
都是真实的。当然,这里我假设程序员熟悉混合模式算法的规则。:)@很高兴知道。