データの入った配列を貰って平均するサブルーチン
不良データがあるとそれを避けて平均を求める。不良かどうかは
logical function ok で判別する。
平均を取るには、データを全部足してデータ数で割るわけだが、 データの足し算の際には、桁落ちで精度を悪くしないように、 real の足し算なら double precision を使うと言う風にしたほうが良い。 ほかも同様で、多量の足し算や掛け算には有効数字の多い変数を使用するべきである。
implicit none
integer, parameter :: n=300
real :: x(n), avr
integer :: i, num, okdatanum, ios
i=1; ios=0
do while( i<=n .and. ios==0 )
read(*,*, iostat=ios, err=990) x(i)
i=i+1
end do
990 continue
if( i >= n ) then
num = n
write(*,*) 'Only first ', num, 'data are used!'
else
num=i-2
end if
! write(*,*) 'num = ', num
! do i=1, num
! write(*,*) i, x(i)
! end do
call average( x, num, avr, okdatanum )
write(*,*) 'Average is ', avr, 'good data number = ', okdatanum
end
subroutine average( x, num, avr, count )
implicit none
integer, intent(in) :: num
real, intent(in) :: x(num)
real, intent(out) :: avr
integer :: count
integer :: i, baddatanum
logical :: ok
double precision :: sum
sum = 0; count = 0 ; baddatanum = 0
do i=1, num
if( ok(x(i), baddatanum)) then
count = count + 1
sum = sum + x(i)
end if
end do
avr = (sum/count)
end subroutine
logical function ok( x, count )
implicit none
real :: x
integer :: count
if( x < -9900 ) then
ok = (5<0)
count = count + 1
else
ok = (5>0)
endif
end function
玉川 2007