分析数值数组的奇怪结果

时间:2015-04-20 17:22:48

标签: arrays fortran fortran90 gfortran

我已经编写了以下程序来查找数组:最大和最大最小值;数量+ ve& - 值;素数和数量完美的数字;平方和,平均值,方差和标准差(最后两个对于了解统计数据的人来说都很熟悉)。

我的问题是,平方和之后的输出是不正确的。你能说出原因吗?我写的程序是:

integer,dimension(10)::num

open(10,file='in.txt')
open(100,file='in-n.txt')
read(100,*)n
do i=1,n
read(10,*)num(i)
end do

l=1
do i=1,n
if(num(i)<=num(l))cycle
l=i
end do
lar=num(l)



l=1
do i=1,n
if(num(i)>=num(l))cycle
l=i
end do
sml=num(l)



k=0
do i=1,n
if(num(i)<0)cycle
k=k+1
end do
n_pos=k



k=0
do i=1,n
if(num(i)>0)cycle
k=k+1
end do
n_neg=k



j=0
do n=1,n
if(num(n)<=1)cycle
m=2
30 if(mod(num(n),m)==0)goto 60
m=m+1
if(m<=sqrt(real(num(n))))goto 30
j=j+1
60 end do
n_prm=j



j=0
do n=1,n
k=0
do i=1,num(n)
    if(mod(num(n),i)==0)k=k+i
end do

if(k==2*num(n))j=j+1
end do
n_per=j



sumsq=0.
do i=1,n
sumsq=sumsq+num(i)**2
end do
sum1=0.
do i=1,n
sum1=sum1+real(num(i))
end do
ave=sum1/float(n)
sum2=0.
do i=1,n
sum2=sum2+(num(i)-ave)**2
end do
var=sum2/float(n-1)
sd=sqrt(var)

write(*,80)lar,nint(sml),n_pos,n_neg,n_prm,n_per,sumsq,ave,var,sd
80 format(1x,'Largest value: ',t30,i2//&
1x,'Smallest value: ',t30,i2//&
1x,'# of positive numbers: ',t30,i2//&
1x,'# of negative numbers: ',t30,i2//&
1x,'# of primes: ',t30,i2//&
1x,'# of perfects: ',t30,i2//&
1x,'Sum of squares: ',t30,f10.5//&
1x,'Average: ',t30,f10.5//&
1x,'Variance: ',t30,f10.5//&
1x,'Standard deviation: ',t30,f10.5)


end

输出结果为:

Largest value:              20
Smallest value:             13
# of positive numbers:      10
# of negative numbers:       0
# of primes:                 5
# of perfects:               0
Sum of squares:             2731.00000
Average:                      14.58333
Variance:                     16.26515
Standard deviation:            4.03301

当我在另一个程序中单独编写程序中有问题的部分时,它可以完美地运行:

integer,dimension(10)::num

open(10,file='in.txt')
open(100,file='in-n.txt')

read(100,*)n
do i=1,n
    read(10,*)num(i)
end do
sumsq=0.
do i=1,n
    sumsq=sumsq+num(i)**2
end do
sum1=0.
do i=1,n
    sum1=sum1+num(i)
end do
ave=sum1/float(n)
sum2=0.
do i=1,n
    sum2=sum2+(num(i)-ave)**2
end do
var=sum2/float(n-1)
sd=sqrt(var)
print*,sumsq,ave,var,sd

end

输出:

2606.00000,            16.0000000,             5.11111116,           2.26077676

数组num的元素是:20,13,17,17,13,18,14,17,16,15。

1 个答案:

答案 0 :(得分:0)

循环

do n=1,n
  ...
end do

或许没有做你认为它做的事情。嗯,确实如此,但它做得更多。

在该循环结束时n具有(因为没有从构造中提前退出),其值大于循环之前的值。您可以找到对此here的讨论。 [我几乎把这个问题称为副本,但需要一点解释才能实现。]

在该循环之后,您的n不再引用num中的元素数量:您的后续循环希望n依赖于破坏的假设。

您不会在固定版本中使用此n循环构思。你需要用这个错误重新编写前面的部分。

因为在此示例中,您分析的元素数量等于数组的大小,使用编译器标志进行边界检查将帮助您识别此问题。但是,如果n最初不是10而是8(或更小),那么您只会引用num的未定义部分:可能是一个更难找到的问题。< / p>