First of all I would define a subroutine that will update the bin count, so in the loop you will just call this subroutine.
do j=1,4000
read(7,*) a, b, c, d, e
call update_bin_count(a, bina, lower, upper)
call update_bin_count(b, binb, lower, upper)
call update_bin_count(c, binc, lower, upper)
call update_bin_count(d, bind, lower, upper)
call update_bin_count(e, bine, lower, upper)
end do
As suggested before I will use:
bin = 20.0*(b(k)-(-3.0))/(3.0-(-3.0))+1
if(bin>=1 .and. bin <=20) binb(bin) = binb(bin) +1
inside the update_bin_count if the bins are regular, otherwise a simple loop will be fine:
subroutine update_bin_count(v, bin, lower, upper)
real v, bin(:), lower(:), upper(:)
integer :: i
do i = 1, size(bin)
if (v >= lower(i) .and. v < upper(i)) then
bin(i) = bin(i) + 1
exit
endif
enddo
end subroutine
The routine should be inside a module otherwise is not going to work as it is using assumed shape arrays.
By the way, every Fortran routine should be defined inside a module in a new software.
Now this is scaling as the number of elements by the number of bins as you can see.
If you have a huge number of elements and a huge number of irregular bins, you may need a different algorithm.