开发者

Solving quadratic equation but getting weird errors

I'm attempting my first program in Fortran, trying to solve a quadratic equation. I have double and triple checked my code and don't see anything wrong. I keep getting "Invalid character in name at (1)" and "Unclassifiable statement at (1)" at various locations. What is wrong with the code?

! This program solves quadratic equations
! of the form ax^2 + bx + c = 0.
! Record:
! Name:             Date:     Notes:
! Damon Robles      4/3/10    Original Code

PROGRAM quad_solv
IMPLICIT NONE

! Variables
REAL :: a, b, c
REAL :: discrim, root1, root2,    
COMPLEX :: comp1, comp2
CHARACTER(len=1) :: correct 

! Prompt user for coefficients.
WRITE(*,*) "This program solves quadratic equations "
WRITE(*,*) "of the form ax^2 + bx + c = 0. "
WRITE(*,*) "Please enter the coefficients a, b, and "
WRITE(*,*) "c开发者_如何转开发, separated by commas:"
READ(*,*) a, b, c
WRITE(*,*) "Is this correct: a = ", a, " b = ", b
WRITE(*,*) " c = ", c, " [Y/N]? "
READ(*,*) correct
IF correct = N STOP
IF correct = Y THEN

! Definition
discrim = b**2 - 4*a*c

! Calculations
IF discrim > 0 THEN
root1 = (-b + sqrt(discrim))/(2*a)
root2 = (-b - sqrt(discrim))/(2*a)
WRITE(*,*) "This equation has two real roots. "
WRITE(*,*) "x1 = ", root1
WRITE(*,*) "x2 = ", root2
IF discrim = 0 THEN
root1 = -b/(2*a)
WRITE(*,*) "This equation has a double root. "
WRITE(*,*) "x1 = ", root1
IF discrim < 0 THEN
comp1 = (-b + sqrt(discrim))/(2*a)
comp2 = (-b - sqrt(discrim))/(2*a)
WRITE(*,*) "x1 = ", comp1
WRITE(*,*) "x2 = ", comp2

PROGRAM END quad_solv


Re the additional question of how to loop back to redo input -- an example program demonstrating loop features of Fortran >= 90. The loop is apparently infinite -- exit controlled by the IF statement exits the loop and makes the loop finite. Also shown is the cycle control, which is used if invalid input is encountered, which would otherwise crash the program. (For example, type "A" as input to the first read, instead of a number.) In this case, the iostat variable acquires a non-zero value, the IF statement activates the cycle, and the rest of the DO loop is skipped, so that the loop cycles anew.

program test_readdata

real :: a, b, c
integer :: ReturnCode
character (len=1) :: correct

ReadData: do

   write (*, '( "This program solves quadratic equations of the form ax^2 + bx + c = 0. " )' ) 
   write (*, '( "Please enter the coefficients a, b, and c, separated by commas: " )', advance='no' )
   read (*,*, iostat=ReturnCode) a, b, c
   if ( ReturnCode /= 0 ) cycle ReadData
   write (*,*) "Is this correct: a = ", a, " b = ", b, " c = ", c
   write (*, '( "Enter Y or N: " )', advance='no' )
   read (*,*, iostat=ReturnCode) correct
   if ( ReturnCode /= 0 ) cycle ReadData
   if ( correct == 'Y'  .or.  correct == 'y' )  exit ReadData

end do ReadData

stop

end program test_readdata

My book recommendation: Fortran 95/2003 explained by Metcalf, Reid and Cohen.


The first thing I noticed with your code is the syntax error at the end of your program.

END

should have preceded the word program

Doesn't your editor highlight your syntax errors?

You can get the student version of ELF 90 pretty inexpensively and it's a good place to start. I would then upgrade to Lahey ELF 95 with the Visual Studio and algorithm flow chart generator which color codes the pathways of the passing of the values.


So many errors... It seems you don't know Fortran basics...

With minimal corrections

! This program solves quadratic equations
! of the form ax^2 + bx + c = 0.
! Record:
! Name:             Date:     Notes:
! Damon Robles      4/3/10    Original Code

PROGRAM quad_solv

  IMPLICIT NONE

  ! Variables
  REAL :: a, b, c
  REAL :: discrim, root1, root2    
  COMPLEX :: comp1, comp2
  CHARACTER(len=1) :: correct 

  ! Prompt user for coefficients.
  WRITE(*,*) "This program solves quadratic equations "
  WRITE(*,*) "of the form ax^2 + bx + c = 0. "
  WRITE(*,*) "Please enter the coefficients a, b, and "
  WRITE(*,*) "c, separated by commas:"
  READ(*,*) a, b, c
  WRITE(*,*) "Is this correct: a = ", a, " b = ", b
  WRITE(*,*) " c = ", c, " [Y/N]? "
  READ(*,*) correct

  IF (correct == 'N') STOP

  IF (correct == 'Y') THEN

    ! Definition
    discrim = b**2 - 4*a*c

    ! Calculations
    IF (discrim > 0) THEN
      root1 = (-b + sqrt(discrim))/(2*a)
      root2 = (-b - sqrt(discrim))/(2*a)
      WRITE(*,*) "This equation has two real roots. "
      WRITE(*,*) "x1 = ", root1
      WRITE(*,*) "x2 = ", root2
    ELSEIF (discrim == 0) THEN
      root1 = -b/(2*a)
      WRITE(*,*) "This equation has a double root. "
      WRITE(*,*) "x1 = ", root1
    ELSE
      comp1 = (-b + sqrt(discrim))/(2*a)
      comp2 = (-b - sqrt(discrim))/(2*a)
      WRITE(*,*) "x1 = ", comp1
      WRITE(*,*) "x2 = ", comp2
    END IF

  END IF  

END PROGRAM quad_solv

P.S. I didn't check the correctness. P.P.S. Always indent your code to make it readable and don't use STOP statement. Each program (or subroutine) should have one entry and one exit. The only right place for STOP is exactly before END PROGRAM statement where it is redundant. So don't use STOP at all.


Some changes: correct IF syntax; constants to be real numbers rather than integers, when appropriate:

IF (CORRECT == "N" ) stop
if ( discrim > 0.0 ) then

Apply at additional locations, and you should be very close. Good luck.

It can be a poor algorithm to test a floating point number for having an exact value. What if rounding error makes disrim have the value 1.0E-30, when perfect arithmetic would give the value zero and indicate a double root?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜