Решая квадратное уравнение, но получая странные ошибки - PullRequest
3 голосов
/ 07 апреля 2010

Я пробую свою первую программу на Фортране, пытаюсь решить квадратное уравнение.Я дважды и трижды проверил свой код и не вижу ничего плохого.Я продолжаю получать «Неверный символ в имени в (1)» и «Неклассифицируемый оператор в (1)» в разных местах.Что не так с кодом?

! 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

Ответы [ 4 ]

2 голосов
/ 08 апреля 2010

По дополнительному вопросу о том, как вернуться к повторному вводу - пример программы, демонстрирующей особенности цикла Fortran> = 90. Цикл, по-видимому, бесконечен - exit , управляемый оператором IF, выходит изцикл и делает цикл конечным.Также показан элемент управления cycle , который используется, если обнаружен неверный ввод, который в противном случае привел бы к аварийному завершению программы.(Например, введите «A» в качестве ввода для первого чтения вместо числа.) В этом случае переменная iostat получает ненулевое значение, оператор IF активирует цикл, а остальная часть цикла DO равнапропущен, так что цикл повторяется.

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

Рекомендация моей книги: Фортран 95/2003 объяснил Меткалфом, Рейдом и Коэном.

1 голос
/ 15 апреля 2010

Первое, что я заметил в вашем коде, это синтаксическая ошибка в конце вашей программы.

END

должно предшествовать слову program

Разве ваш редактор не выделяет ваши синтаксические ошибки?

Вы можете получить студенческую версию ELF 90 довольно недорого, и это хорошее место для начала. Затем я бы обновился до Lahey ELF 95 с Visual Studio и генератором блок-схем алгоритмов, цвет которого определяет пути передачи значений.

0 голосов
/ 07 апреля 2010

Некоторые изменения: правильный синтаксис IF; константы, чтобы быть действительными числами, а не целыми числами, когда это уместно:

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

Подайте заявку на дополнительные места, и вы должны быть очень близко. Удачи.

Это может быть плохой алгоритм для проверки числа с плавающей запятой на наличие точного значения. Что если ошибка округления заставит disrim иметь значение 1.0E-30, когда совершенная арифметика выдаст нулевое значение и покажет двойной корень?

0 голосов
/ 07 апреля 2010

Так много ошибок ... Кажется, вы не знаете основ Fortran ...

С минимальными исправлениями

! 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. Я не проверял правильность. P.P.S. Всегда делайте отступ в своем коде, чтобы сделать его читабельным, и не используйте оператор STOP. Каждая программа (или подпрограмма) должна иметь одну запись и один выход. Единственное правильное место для STOP - это точно перед оператором END PROGRAM, где оно является избыточным. Так что вообще не используйте STOP.

...