Решаю квадратное уравнение, но получаю странные ошибки

Я пробую свою первую программу на Фортране, пытаясь решить квадратное уравнение. Я дважды и трижды проверил свой код и не вижу ничего плохого. Я продолжаю получать «Недопустимый символ в имени в (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

person Damon    schedule 06.04.2010    source источник


Ответы (4)


Дополнительный вопрос о том, как вернуться к повторному вводу - пример программы, демонстрирующий функции цикла Фортрана >= 90. Цикл, по-видимому, бесконечен - выход, управляемый оператором IF, выходит из цикла и делает петлю конечной. Также показан элемент управления цикл, который используется, если встречается неверный ввод, что в противном случае может привести к сбою программы. (Например, введите «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

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

person M. S. B.    schedule 08.04.2010
comment
Спасибо за подсказки и образец кода, я попытаюсь включить его в свою программу... Хорошая новость в том, что я смог скомпилировать и запустить... если ввод правильный с первого раза :). - person Damon; 08.04.2010

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

END

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

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

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

person user317010    schedule 14.04.2010

Столько ошибок... Похоже, вы не знаете основ Фортрана...

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

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

person Wildcat    schedule 06.04.2010
comment
И если кто-то хочет преждевременно завершить программу, что следует использовать? - person Rook; 07.04.2010
comment
Хороший вопрос... Я пытаюсь научиться программировать по книге на Фортране в рамках подготовки к аспирантуре по квантовой химии. Опыта программирования нет вообще. Любые предложения для хороших учебных ссылок? - person Damon; 07.04.2010
comment
Использование STOP было моим невежественным способом остановить выполнение программы, если ввод был неправильным. Я не понял, как заставить его снова запрашивать ввод... Еще раз спасибо. - person Damon; 07.04.2010
comment
@DAmon: лучшая книга для изучения с самого начала - это Fortran 90 Эллиса, Филипса и Лахи. После того, как вы прочтете первые несколько глав, вам также понадобится копия Fortran 95/2003 Explained, написанная Меткалфом, Ридом и Коэном. Некоторые функции в более поздних стандартах реализуют полезные вещи, отсутствующие в стандарте 90. - person High Performance Mark; 07.04.2010
comment
Спасибо, Марк, посмотрю! - person Damon; 07.04.2010
comment
@Idigas: проблема с оператором STOP такая же, как и с оператором GOTO. На начальных этапах они усложняют обучение, позволяя писать плохо структурированные программы. Следующее, что СТОП без следования коду останова бесполезен. Но коды остановки зависят от процессора. Это означает, что поведение не определено стандартом FORTRAN 90/95/2003. Эти стандарты понятия не имеют, что такое код выхода, что такое процесс и так далее. Еще раз СТОП не так полезен. - person Wildcat; 07.04.2010

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

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

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

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

person M. S. B.    schedule 06.04.2010
comment
Спасибо за ваш вклад, пытаюсь научиться программировать в первый раз! - person Damon; 07.04.2010