Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Fortran > [General] Защита от мнимых чисел


Автор: FFFU 23.10.2010, 11:15
Здравствуйте!
Нам в институте задали сделать калькулятор на Фортране. 
В числе прочего нужно еще и сделать защиту от вычисления мнимых чисел.
Код

write(*,*)"1+,2-,3*,4:,5^"
read(*,*) key
write(*,*)"a="
read(*,*) a
    10 write(*,*)"b="
read(*,*) b
if(key.eq.1)print*, a+b
if(key.eq.2)print*, a-b
if(key.eq.3)print*, a*b
if(key.eq.4.and.b.eq.0) then
print*, "Делить на ноль нельзя"
goto 10
endif
if(key.eq.5.and.a.lt.0.and___вот тут непонятно что написать___) then
print*, "не работаем с мнимыми числами"
goto 10
endif
if(key.eq.4)print*, a/b
if(key.eq.5)print*, a**b
end

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

Автор: kemiisto 23.10.2010, 12:23
Во-первых, забудьте о goto.
Во-вторых, используйте == вместо .eq., < вместо .lt. и т.д.
В-третьих, я что-то с трудом понимаю, как из вещественного числа при возведении его в вещественную степень можно получить комплексное число? Я что-то упустил? 

Автор: Фантом 23.10.2010, 13:46
Цитата(kemiisto @  23.10.2010,  12:23 Найти цитируемый пост)
Во-первых, забудьте о goto.
Во-вторых, используйте == вместо .eq., < вместо .lt. и т.д.

И заодно еще вместо цепочки if'ов конструкцию
Код

select case(key)
  case(1)  
     ...
  case(2)  
     ....
  ...
end select


Цитата(kemiisto @  23.10.2010,  12:23 Найти цитируемый пост)
В-третьих, я что-то с трудом понимаю, как из вещественного числа при возведении его в вещественную степень можно получить комплексное число? Я что-то упустил?  

А если возвести -1 в степень 0.5? Оба числа вещественные...  smile 

Автор: kemiisto 23.10.2010, 13:48
Цитата(Фантом @  23.10.2010,  14:46 Найти цитируемый пост)
А если возвести -1 в степень 0.5? Оба числа вещественные...

Ах ну да... smile Чувствовалось, что упускаю что-то...

Добавлено @ 14:01
Так стоп. Я тут подумал. Думаю, если a отрицательно, то его можно возводить только в целую степень. В вещественную в любом случае не получится. Для возведения в вещественную степень нужно применять какую-то формулу. Например, a^b = e^(b * lna). А логарифм определён только для положительных чисел.

Автор: Фантом 23.10.2010, 14:40
Цитата(kemiisto @  23.10.2010,  13:48 Найти цитируемый пост)
Так стоп. Я тут подумал. Думаю, если a отрицательно, то его можно возводить только в целую степень. В вещественную в любом случае не получится. Для возведения в вещественную степень нужно применять какую-то формулу. Например, a^b = e^(b * lna). А логарифм определён только для положительных чисел.

Вообще-то в Фортране есть встроенная операция возведения в степень.  smile Другое дело, что этот случай она действительно обработает не так, как ожидается - попытка вычислить "в лоб" (-1)**0.5 выдаст какой-нибудь вариант NaN. Но не потому, что "нельзя", а потому, что в этом случае результат операции формально должен быть вещественным. А если явно сделать первый операнд комплексным (например,  (-1,0)**0.5), то все сработает так, как надо.

Автор: kemiisto 23.10.2010, 14:45
Фантом, оно понятно. Я просто к тому, что в этом условии
Цитата(FFFU @  23.10.2010,  12:15 Найти цитируемый пост)
if(key.eq.5.and.a.lt.0.and___вот тут непонятно что написать___)

проверять, собственно, ничего больше и не надо, если a и b - real, а комплексных чисел надо избегать.

Автор: Фантом 23.10.2010, 14:55
Цитата(kemiisto @  23.10.2010,  14:45 Найти цитируемый пост)
но понятно. Я просто к тому, что в этом условии
проверять, собственно, ничего больше и не надо, если a и b - real, а комплексных чисел надо избегать.

А, тогда да.

Автор: kemiisto 23.10.2010, 14:58
Цитата(Фантом @  23.10.2010,  15:55 Найти цитируемый пост)
А, тогда да.

В общем, если a и b - real, как-то так:

Код

program main

  implicit none
  
  real :: a, b
  integer :: key
  
  write (*, *) "1 +, 2 -, 3 *, 4 :, 5 ^"
  read  (*, *) key
  write (*, *) "a = "
  read  (*, *) a
  write (*, *) "b = "
  read  (*, *) b
  
  select case (key)
    case (1)
      write (*, *) a + b 
    case (2)
      write (*, *) a - b
    case (3)
      write (*, *) a * b
    case (4)
      if (b == 0) then
        write (*, *) "Error: a : b where b = 0!"
      else
        write (*, *) a / b
      end if
    case (5)
      if (a < 0) then
        write (*, *) "Error: a^b where a < 0!"
      else
        write (*, *) a ** b
      end if
    case default
  end select

end program main


Автор: FFFU 23.10.2010, 21:04
но ведь отрицательные числа можно возводить в степень...

Автор: kemiisto 23.10.2010, 21:08
Цитата(FFFU @  23.10.2010,  22:04 Найти цитируемый пост)
но ведь отрицательные числа можно возводить в степень...

Можно, но есть нюансы. Я же писал выше, что операция ** в Fortran для отрицательных вещественных чисел вернёт результат, только если степень будет целым числом. Иначе всё равно будет NaN.

Автор: FFFU 24.10.2010, 00:28
большое спасибо! smile 
PS про case тоже учту

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)