mangesh
mangesh

Reputation: 61

Fortran do loop not calculating the entered variable

When I run the code for Celsius only I am getting the result below the code:

    program temperature
! F C temperature conversion
implicit none
real :: celcius=0.0, fahrenheit=0.0

integer:: t,n
print *,'enter the number of lines'
read*, n
do n=1,n
print*,'enter the  value of t: one per line',n
read*, t
celcius=5/9*(t-32)

enddo
do n=1,n
print*, t, celcius
enddo
end program

result

    enter the number of lines
3
 enter the  value of t: one per line           1
50
 enter the  value of t: one per line           2
20
 enter the  value of t: one per line           3
10
          10   0.00000000E+00
          10   0.00000000E+00
          10   0.00000000E+00
          10   0.00000000E+00

It's clear that compiler is not picking the value of t in the calculation.

Upvotes: 0

Views: 550

Answers (2)

John Bollinger
John Bollinger

Reputation: 180058

You have at least three problems:

  1. The expression 5/9*(t-32) is evaluated left-to-right, so the 5/9 part is an integer (truncating) division, always producing 0. The product of zero with anything finite is zero. There are several ways you could address that, but one of the simpler would be to rewrite the expressions as 5 * (t - 32) / 9.

  2. Your variables t and celcius are scalars. They hold only one number at a time each. In your first loop you assign multiple values to each of them them in sequence. When you later perform a second loop to print the results, only the last value assigned to each variable will be accessible. If you must defer output until after reading all the input then one way to handle it would be to make t and celcius arrays of sufficient size, and store your values in different elements. (Also note: the correct spelling of the English word is "celsius".)

  3. Per @albert in comments, after an indexed do loop finishes, the value of the iteration variable is the one it would have had in the next iteration of the loop, if there were one. Therefore, by using variable n both as your iteration variable and your upper bound, you are causing its value to be different after each loop than it was before. There are several ways you could address this, but I urge you to simply avoid reusing n as your iteration variable. There is no efficiency to be gained by avoiding a for-purpose iteration variable.

Upvotes: 1

Pierre de Buyl
Pierre de Buyl

Reputation: 7293

You have several options.

  1. Store the input in an array and process the array.

    program temperature
      ! F C temperature conversion
      implicit none
    
      real, allocatable :: fahrenheit(:)
      integer:: n
    
      print *,'enter the number of lines'
      read*, n
      allocate(fahrenheit(n))
      print*,'enter the  value of t: all items on one line'
      read*, fahrenheit
      print *, 'F: ', fahrenheit
      print *, 'C:', fahrenheit_to_celcius(fahrenheit)
    
    contains
    
      pure elemental function fahrenheit_to_celcius(t_f) result(t_c)
        real, intent(in) :: t_f
        real :: t_c
    
        t_c = 5.*(t_f-32.)/9.
    
      end function fahrenheit_to_celcius
    
    end program
    
  2. Process the inputs one at a time

    program temperature
      ! F C temperature conversion
      implicit none
    
      real :: fahrenheit
      integer:: i, n
    
      print *,'enter the number of lines'
      read*, n
    
      do i = 1, n
         print*,'enter the  value of t: one per line',n
         read*, fahrenheit
         print *, 'F: ', fahrenheit, 'C:', fahrenheit_to_celcius(fahrenheit)
      enddo
    
    contains
    
      pure elemental function fahrenheit_to_celcius(t_f) result(t_c)
        real, intent(in) :: t_f
        real :: t_c
    
        t_c = 5.*(t_f-32.)/9.
    
      end function fahrenheit_to_celcius
    
    end program
    

Note that I have used the elemental keyword for the function. It means that you can pass a scalar as well as an array. This is a nice solution for direct computations such as the one here: the routine fahrenheit_to_celcius is identical in both cases.

I fixed the 5/9 (that returns 0) and the mixed up variables as well.

Upvotes: 1

Related Questions