分析数值数组的奇怪结果

Weird results analysing a numeric array

我编写了以下程序来查找数组中的:最大和最小值; +ve & -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。

循环

do n=1,n
  ...
end do

也许并不像您认为的那样。好吧,确实如此,但它的作用更多。

在该循环结束时 n 有一个比循环之前大 1 的值(因为没有提前退出构造)。您可以找到对此 here 的讨论。 [我几乎可以称这个问题为该问题的重复,但需要一些解释才能到达那里。]

在该循环之后,您的 n 不再指代 num 中的元素数量:您以后希望 n 是这样的循环依赖于一个错误的假设。

您没有在固定版本中使用这个 n 循环想法。这个错误需要重写前面的部分。

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