为什么这个fortran程序只产生零?当我打印出来时,到处都是-0.00000!我做错了什么?在matlab中它运行得很好。我没有看到为什么它不诚实的原因!
它似乎是它的一部分。如果我将x设置为等于某个十进制数就可以了。
program main
implicit none
integer iMax, jMax
double precision, dimension(:,:), allocatable :: T
double precision x, dx,f,L2old,L2norm,y
integer i, j,n,bc
n=10
allocate(T(1:n+2, 1:n+2))
T=0.0d0
do i=2,n+1
do j=2,n+1
x=(j+1)*1/24
y=(i+1)*1/24
T(i,j)= -18*(x**2+y**2)**2
Write(*,*)'T(',i,'',j,'', T(i,j)
end do
end do
Write(*,*)'T(1,1)',T(1,1)
end program main
答案 0 :(得分:3)
x=(j+1)*1/24
1/24
是一个整数除法,向下舍入为0.你应该能够通过使至少一个操作数浮点来强制浮点除法,
e.g。
x=(j+1)*1.0/24.0
答案 1 :(得分:1)
正如Jim Lewis所指出的,OP问题的答案确实是使用的整数除法。
毫无疑问,我认为重要的是要指出应该如何记下浮点分数。正如OP的程序所示,x
属于DOUBLE PRECISION
类型。那么正确的结果应该是
x=(j+1)*1.0D0/24.0D0
这里的区别在于,现在您确保除法的发生精度与声明x
的精度相同。
以下程序演示了问题::
program test
WRITE(*,'(A43)') "0.0416666666666666666666666666666666..."
WRITE(*,'(F40.34)') 1/24
WRITE(*,'(F40.34)') 1.0/24.0
WRITE(*,'(F40.34)') 1.0D0/24.0
WRITE(*,'(F40.34)') 1.0D0/24.0D0
end program test
作为输出
0.0416666666666666666666666666666666...
0.0000000000000000000000000000000000
0.0416666679084300994873046875000000
0.0416666666666666643537020320309239
0.0416666666666666643537020320309239
你清楚地看到了差异。第一行是数学正确的结果。第二行是导致零的整数除法。第三行显示分区计算为REAL
而第四和第五行位于DOUBLE PRECISION
时的输出。请注意,在我的情况下,REAL
表示32位浮点数,DOUBLE PRECISION
表示64位版本。 REAL
和DOUBLE PRECISION
的精度和表示都取决于编译器,并且未在the Standard中定义。它只要求DOUBLE PRECISION
的精度高于REAL
。
4.4.2.3真实类型
1 实数类型的值接近数学实数。处理器应提供两种或多种近似方法,为真实类型的数据定义值集。每个这样的方法具有表示方法,并且由类型类型参数KIND的值表征。近似方法的种类型参数由内在函数KIND(13.7.89)返回。
5 如果使用类型关键字REAL而没有kind类型参数,则 指定了具有默认实类的实数类型,类型值为 KIND(0.0)。类型说明符DOUBLE PRECISION指定类型为real 双精度的;种类值是KIND(0.0D0)。该 双精度实数逼近法的小数精度 应大于默认的实际方法。
这实际上意味着,如果您希望确保使用32位,64位或128位浮点表示完成计算,建议您使用内部模块{{1}中定义的正确KIND
值}}
13.8.2.21 REAL32,REAL64和REAL128
1 这些名为常量的默认整数标量的值应为 那些指定REAL类型的类型参数 以比特表示的存储大小分别为32,64和128。如果, 对于任何这些常量,处理器支持多种类型 对于那个大小,它取决于处理器,提供哪种类型的值。 如果处理器不支持任何特定大小,那么常量 如果处理器支持更大尺寸的类型,则应等于-2 否则为-1。
所以这将导致以下代码
ISO_FORTRAN_ENV