简单的程序,只产生零,bug?

时间:2016-10-29 00:07:51

标签: fortran fortran90

为什么这个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

2 个答案:

答案 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位版本。 REALDOUBLE 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