分析数值数组的奇怪结果
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
的未定义部分:可能是一个更难找到的问题。
我编写了以下程序来查找数组中的:最大和最小值; +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
的未定义部分:可能是一个更难找到的问题。