Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [General] cуществует ли треугольник? 
:(
    Опции темы
TepH
Дата 24.10.2010, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.10.2010

Репутация: нет
Всего: нет



Помогите пожалуйста. Нужно написать программу, по которой можно узнать по введённым длинам сторон, существует такой треугольник или нет, а если существует, то какой он: равносторонний, равнобедренный, прямо-,остро-, тупоугольный.
Так вот, я написал, но при вводе длин 0,3; 0,4; 0,5 программа выдаёт, что треугольник остроугольный, хотя должен выдавать, что прямоугольный. Судя по всему, это происходит из-за погрешности преобразований чисел в двоичный код и обратно. Если посмотреть просто на умножение этих чисел, представляя числа, как double precision, получается, что, как я полагаю при возведении в квадрат числа, квадрат которого равен меньше 0,1 , он выдаёт такую бяку. В итоге для квадрата числа 0,3 получается что-то вроде 0,090000642. Из-за этого и происходит ошибка. Подскажите пожалуйста, как избавиться от этого?

Вот текст мой программы:
Код

       program TRI
       real  a, b, c
       print*, 'Введите три стороны'
       read*,a,b,c
       s=a
       d=b
       do 10 i=1, 2
        if(s .lt. d) s=d
        d=c
 10    continue
       print*,'Наибольшая сторона:',s
       if(s .eq. a)then
          if(s .lt. b+c) then
           if(b**2+c**2 .gt. a**2) print*, 'Остроугольный'
           if(b**2+c**2 .lt. a**2) print*, 'Тупоугольный'
           if(b**2+c**2 .eq. a**2) print*, 'Прямоугольный'
            goto 20
           endif
 
       elseif(s .eq. b) then
          if(s .lt. a+c) then
           if(a**2+c**2 .gt. b**2) print*, 'Остроугольный'
           if(a**2+c**2 .lt. b**2) print*, 'Тупоугольный'
           if(a**2+c**2 .eq. b**2) print*, 'Прямоугольный'
            goto 20
           endif
 
       elseif(s .eq. c) then
          if(s .lt. a+b) then
           if(a**2+b**2 .gt. c**2) print*, 'Остроугольный'
           if(a**2+b**2 .lt. c**2) print*, 'Тупоугольный'
           if(a**2+b**2 .eq. c**2) print*, 'Прямоугольный'
            goto 20
           endif
       endif
         goto 40
 
 20    if(a .eq. b .and. a .eq. c) then
         print*, 'Равносторонний'
         goto 30
       endif
 
       if(a .eq. b .and. a .ne. c .or. a .eq. c .and. a .ne. b) goto 25
       if(b .eq. c .and. b .ne. a) then
        goto 25
        else
         goto 30
       endif
 
 25   print*, 'Равнобедренный'
 
 30    print*, 'Треугольник существует'
        goto 100
 40    print*, 'Треугольник не существует'
        goto 100
 
 
 100    end
 

PM MAIL   Вверх
FCM
Дата 24.10.2010, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Сравнивать вещественные числа  не есть хорошо в любом языке программирования (в некоторых C++ компиляторах даже предусмотрены предупреждения на сей счет).
Можно попробовать задать некий малый порог  и сравнивать с ним модуль разности вещественных чисел.

Кроме того, real лучше заменить на real(8).

(И что за компилятор используется?
В современных (в т.ч. бесплатных) компиляторах 
- максимум двух и более чисел можно найти с помощью функции max(a,b,c, ...). 
- операторы сравнения  можно писать в естественной форме ==, >, < и т.п.
- циклы лучше писать в так называемой блочной форме do...enddo. )



Это сообщение отредактировал(а) FCM - 24.10.2010, 19:23
PM MAIL   Вверх
TepH
Дата 24.10.2010, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.10.2010

Репутация: нет
Всего: нет



Компиллятор... Даже и не знаю. Мы делаем через программу Putty. Через неё заходим на Unix-сервер и там делаем.

"Можно попробовать задать некий малый порог  и сравнивать с ним модуль разности вещественных чисел."
Знать бы как... Я ж сам не программист, а тут начали проходить Фортран лабораторными работами, а по обучалке читаем теорию. Но там нет такого(там много чего нету). Преподы говорят, что надо бы, чтобы мы сами додумались...
PM MAIL   Вверх
Фантом
Дата 24.10.2010, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 5
Всего: 49



Цитата(TepH @  24.10.2010,  22:30 Найти цитируемый пост)
"Можно попробовать задать некий малый порог  и сравнивать с ним модуль разности вещественных чисел."
Знать бы как... 

Например, так:
Код

if(abs(a**2+c**2-b**2)<1E-6) print *, 'Прямоугольный'


PM   Вверх
FCM
Дата 25.10.2010, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Цитата(Фантом @  24.10.2010,  23:26 Найти цитируемый пост)
Например, так:

if(abs(a**2+c**2-b**2)<1E-6) print *, 'Прямоугольный'



Поскольку там несколько подобных сравнений, лучше ввести отдельную переменную или константу 
и сравнивать с ней.
PM MAIL   Вверх
Фантом
Дата 25.10.2010, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 5
Всего: 49



Цитата(FCM @  25.10.2010,  08:28 Найти цитируемый пост)
Поскольку там несколько подобных сравнений, лучше ввести отдельную переменную или константу 
и сравнивать с ней. 

Да, конечно.
PM   Вверх
FCM
Дата 25.10.2010, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Программу можно построить по другому - введя подпрограмму сортировку (например так, чтобы a<=b<=c) чтобы не воодить s и не плодить if-ы




Это сообщение отредактировал(а) FCM - 25.10.2010, 14:02
PM MAIL   Вверх
TepH
Дата 25.10.2010, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.10.2010

Репутация: нет
Всего: нет



Цитата(Фантом @  24.10.2010,  23:26 Найти цитируемый пост)
if(abs(a**2+c**2-b**2)<1E-6) print *, 'Прямоугольный'


Спасибо. С этим работает. Я, правда, не совсем понимаю, что это значит...
Странно, при вводе 3; 4; 5, он пишет просто прямоугольный, а при вводе 0,3; 0,4; 0,5 что и прямоугольный и остроугольный...

PM MAIL   Вверх
FCM
Дата 25.10.2010, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Цитата(TepH @  25.10.2010,  13:36 Найти цитируемый пост)
Цитата(Фантом @  24.10.2010,  23:26 Найти цитируемый пост)
if(abs(a**2+c**2-b**2)<1E-6) print *, 'Прямоугольный'

Спасибо. С этим работает. Я, правда, не совсем понимаю, что это значит...
Странно, при вводе 3; 4; 5, он пишет просто прямоугольный, а при вводе 0,3; 0,4; 0,5 что и прямоугольный и остроугольный...


Потому что при введении eps надо согласовать все условия.

Программу можно построить по другому - введя подпрограмму сортировки , чтобы не воодить s и не плодить if-ы

Код

program TRI
       real(8) a, b, c, eps
       eps = 1.d-8
       print*, 'Enter 3 sides'
       read*, a,b,c
       call sort3(a,b,c) ! Сортируем так. чтобы a<=b<=c
       print*, a,b,c
       if( c<eps .or. b<eps .or. a<eps .or. (c - a - b)>eps  ) stop 'Treugolnik does not exist!'
       if( abs(a-b)<eps .and. abs(b-c)<eps )  then
          print*, 'Ravnostoronnii'
       else
           if( abs(a-b)<eps  .or. abs(c-b)<eps  .or. abs(a-c)<eps  ) print*,  'Ravnobedrennyi'
           if( (a*a + b*b - c*c) > eps )  then
              print*, 'Ostrougolnyi'
           else if( (a*a + b*b - c*c) < -eps ) then
              print*, 'Tupougolnyi'
           else
              print*, 'Pryamougolnyi'
           endif
       endif
end

subroutine sort3(a,b,c)
    real(8) a,b,c
    call sort2(a,b)  ! переставляем значения так , что a<=b
    call sort2(b,c)  ! переставляем значения так , что b<=c
    call sort2(a,b)  ! переставляем значения так , что a<=b
end

subroutine sort2(x,y)
    real(8) x, y, t
    if(x>y) then
       t = y
       y = x
       x = t
    endif
end


Выше 
- если используется f77,  оператор > надо заменить на .gt.  , а оператор < на .lt.
- еще неидеально относительно выбора eps - возможно его лучше выбирать исходя из величины наиболее длинной стороны или т.п.
- ну и надо проверить правильно ли работает сортировка 



Это сообщение отредактировал(а) FCM - 28.10.2010, 09:53
PM MAIL   Вверх
TepH
Дата 25.10.2010, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.10.2010

Репутация: нет
Всего: нет



Что-то на вашу большую программу шибко ругается. 


Код

tri2.for:24.7:

       end
      1
Error: END IF statement expected at (1)
tri2.for:26.6:

      subroutine sort3(a,b,c)
     1
Error: Unclassifiable statement at (1)
tri2.for:27.16:

       real(8) a, b, c
               1
Error: Symbol 'a' at (1) already has basic type of REAL
tri2.for:30.6:

      end
     1
Error: END IF statement expected at (1)
tri2.for:32.6:

      subroutine sort2(x,y)
     1
Error: Unclassifiable statement at (1)
tri2.for:33.72:

       real(8) x, y, t
                                                                       1
Error: Unexpected data declaration statement at (1)
tri2.for:39.6:

      end
     1
Error: END IF statement expected at (1)
Error: Unexpected end of file in 'tri2.for'

PM MAIL   Вверх
FCM
Дата 25.10.2010, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Попробй еще раз (ранее была неточность в sort3):
В gfortran работает.
Код

       program TRI
           real(8) a, b, c, eps
           eps = 1.d-8
           print*, 'Enter 3 sides'
           read*, a,b,c
           call sort3(a,b,c) ! Сортируем значения так, чтобы a<=b<=c
           print*, a,b,c
           if( c<eps .or. b<eps .or. a<eps .or. (a + b - c) < eps  ) stop 'Treugolnik does not exist!'
           if( abs(a-b)<eps .and. abs(b-c)<eps )  then
               print*, 'Ravnostoronnii'
           else
               if( abs(a-b)<eps  .or. abs(c-b)<eps  .or. abs(a-c)<eps  ) print*,  'Ravnobedrennyi'
               if( (a*a + b*b - c*c) > eps )  then
                   print*, 'Ostrougolnyi'
               else if( (a*a + b*b - c*c) < -eps ) then
                   print*, 'Tupougolnyi'
               else
                   print*, 'Pryamougolnyi'
               endif
            endif
       end

       subroutine sort3(a,b,c)
            real(8) a,b,c
            call sort2(a,b)  ! переставляем значения так , что a<=b
            call sort2(b,c)  ! переставляем значения так , что b<=c
            call sort2(a,b)  ! переставляем значения так , что a<=b
       end

       subroutine sort2(x,y)
           real(8) x, y, t
           if(x>y) then
               t = y
               y = x
               x = t
           endif
       end



А если продолжает ругаться выложи весь код, на который ругается - может при копировании и вставке ошибки?

Это сообщение отредактировал(а) FCM - 25.10.2010, 15:47
PM MAIL   Вверх
TepH
Дата 25.10.2010, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.10.2010

Репутация: нет
Всего: нет



А теперь работает... Только тут такое дело, уж простите за то, что так гружу Вас, но если ввести, 1, 2, 3 то он пишет, что треугольник тупоугольный, а его, по-идее, не должно существовать (0н будет, так называемый, развёрнутый, т.е. прямая линия)... А в этой программе я даже не знаю, куда сунуться, чтобы это подправить. Что-то потыкался, а это вообще ничего не даёт.


А gfortran  - это название компиллятора чтоли?
PM MAIL   Вверх
FCM
Дата 25.10.2010, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Вместо строки
Код

if( c<eps .or. b<eps .or. a<eps .or. (c - a - b)> eps ) stop 'Treugolnik does not exist!'

лучше так (в предыдущем своем посте тоже поправил)
Код

if( c<eps .or. b<eps .or. a<eps .or. (a + b - c)<eps ) stop 'Treugolnik does not exist!'


Цитата(TepH @  25.10.2010,  14:41 Найти цитируемый пост)
А gfortran  - это название компиллятора чтоли? 

gfortran - фортран-компилятор из GCC-коллекции (может использоваться как в Linux, так и в Windows). Текщая версия GCC 4.5.x.


Это сообщение отредактировал(а) FCM - 25.10.2010, 15:49
PM MAIL   Вверх
FCM
Дата 25.10.2010, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Возможно, для упрощения, в данном примере, для вводимых чисел можно снять сравнение с использованием порога eps , и оставить eps-проверку только в критических местах. 
Будет примерно так:
 
Код

        program TRI
           real(8) a, b, c, eps
           eps = 1.d-8
           print*, 'Enter 3 sides'
           read*, a,b,c
           call sort3(a,b,c) ! Сортируем так. чтобы a<=b<=c
           print*, a,b,c
           if( c <= 0.d0 .or. b <= 0.d0 .or. a <= 0.d0 .or. (a + b - c) <= 0.d0 ) stop 'Treugolnik does not exist!'
           if( a == b .and. b == c )  then
               print*, 'Ravnostoronnii'
           else
               if( a == b  .or. c == b  .or. a == c  ) print*,  'Ravnobedrennyi'
               if( (a*a + b*b - c*c) > eps )  then
                   print*, 'Ostrougolnyi'
               else if( (a*a + b*b - c*c) < -eps ) then
                   print*, 'Tupougolnyi'
               else
                   print*, 'Pryamougolnyi'
               endif
           endif
       end

       subroutine sort3(a,b,c)
           real(8) a,b,c
           call sort2(a,b)  ! переставляем значения так , что a<=b
           call sort2(b,c)  ! переставляем значения так , что b<=c
           call sort2(a,b)  ! переставляем значения так , что a<=b
       end
      subroutine sort2(x,y)
           real(8) x, y, t
           if(x>y) then
                t = y
                y = x
                x = t
           endif
       end




Это сообщение отредактировал(а) FCM - 25.10.2010, 16:30
PM MAIL   Вверх
TepH
Дата 25.10.2010, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.10.2010

Репутация: нет
Всего: нет



Хм. Заработало, вроде как... А я был близок к разгадке, когда искал, как подправить. 

А, дошло. "a" всегда меньшее, "с" - большее.
Поэтому в облегчённом и равенство а=в и в=с (правда бежать пора, потом посмотрю)
Спасибо.
Вы тут писали, пока, видимо, не исправили, что мне не стоит так, что я не знаю куда сунуться,  раз учусь в техническом. Пожалуй Вы правы.
Я в технаре учился, там, в общем-то железятник, хоть мы немного проходили qbasic  и Turbo Pascal, но там как-то не так всё... И то, почти только ознакомительно.
Поэтому довольно сложно не зная сразу программы писать, пусть и простейшие...
PM MAIL   Вверх
FCM
Дата 25.10.2010, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Цитата(TepH @  25.10.2010,  16:48 Найти цитируемый пост)
А, дошло. "a" всегда меньшее, "с" - большее.
Поэтому в облегчённом и равенство а=в и в=с (правда бежать пора, потом посмотрю)


Если имеется в виду
Код

if( a == b .and. b == c )  then
    print*, 'Ravnostoronnii'

то не поэтому.
Просто из a==b и b==c   следует   a=c.


Это сообщение отредактировал(а) FCM - 25.10.2010, 17:24
PM MAIL   Вверх
TepH
Дата 26.10.2010, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.10.2010

Репутация: нет
Всего: нет



Цитата(FCM @  25.10.2010,  17:23 Найти цитируемый пост)
то не поэтому. Просто из a==b и b==c   следует   a=c.

Ну это я не туда глянул. Я имел в виду при сортировке, "а" становится меньшим, а "с" - бОльшим.

и получается, что код действует:
Код

if( a == b  .or. c == b  .or. a == c  ) print*,  'Ravnobedrennyi'


Спасибо, вы мне очень помогли! Надеюсь, сегодня получится сдать.

Только я никак не могу понять, что значит 
"0.d0"  - 0,0*10 в степени 0?
Код

if( c <= 0.d0 .or. b <= 0.d0 .or. a <= 0.d0 .or. (a + b - c) <= 0.d0 )

и почему eps'у присваивается число 1.d-8, а не 1.e-8. В чём разница между d и e?
Я пробовал менять, ничего не изменилось, вроде как.
Код

eps = 1.d-8


PM MAIL   Вверх
FCM
Дата 26.10.2010, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Цитата(TepH @  26.10.2010,  15:03 Найти цитируемый пост)
Только я никак не могу понять, что значит 
"0.d0"  - 0,0*10 в степени 0?


Если в программе используется real(8), то буквальные константы желательно объявлять тоже как real(8).
1.e-8 - имеет тип real, но при присвоении real(8)-переменной преобразуется к real(8)
1.d-8  сразу имеет тип real(8).
Кстати, вместо 1.d-8 можешь попробовать и другие значения порога. 


0.d0 - просто 0 типа real(8).  

Это сообщение отредактировал(а) FCM - 26.10.2010, 15:13
PM MAIL   Вверх
TepH
Дата 6.11.2010, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.10.2010

Репутация: нет
Всего: нет



Не сочтите за наглость, но я опять не справляюсь...
Так и знал, что со следующей тоже не справлюсь, лучше б про неё спросил... Наверное, я так буду думать с каждым последующим заданием...

Но, я вс же надеюсь её сам выполнить. Поэтому не стал тему создавать ещё одну. Задание большое, делается подобными циклами, поэтому не должно бы быть особых трудностей. Но у меня не получается ввести массив, при выводе он всё по нулям выдаёт и соответственно, ни минимум, ни максимум не существует.
Где-то я не так делаю в именовании массива, мне кажется.

Надо сделать функцию из введённого количества элементов, найти минимум, максимум и номера максимального и минимального элементов, среднеквадратичные, ещё какие-то, относительное количество положительных и отрицательных элементов. Ну, там по формулам всё. Я пока только ввёл массив, и масксимум-минимум. Решил проверить, а ничего не работает, выдаёт нули...
Я менял всё, что мне приходило в голову, но ничего, или ошибку выдаёт, или по нулям.
Где параметр:
Код

!      parameter (n=600)

Я пробовал написать, к примеру:
Код

      parameter (n=600)
      dimension x(n), y(n)


Код

      program FUNC TEST
      integer Nx, k, l, i
      real h, Ma, Mi,  x, y
!      parameter (n=600)
      dimension x(600), y(600)

 10   print*, 'введите количество шагов (30-500)'
      read*, Nx
      if(Nx < 30 .or. Nx > 500) then
       print*, 'Ошибка. Введите заново'
       goto 10
      endif

      h=1/Nx
      do i=1, Nx+1

        x(i)=i*h
        y(i)=x(i)*(1-x(i))-1/8
        Ma=y(1)
      enddo
c     ищем максимум функции
      do i=1, Nx+1
c       M=y(1)
       if(y(i) > Ma) then
        Ma=y(i)
        K=i
       endif
      enddo
      Mi=y(1)
c     ищем минимум функции
      do i=1, Nx+1
       if(y(i) < Min) then
        Mi=y(i)
        l=i
       endif
      enddo

      do i=1, Nx+1
       print*, x(i),    y(i)
!      print*, Ma, '   ', k
      enddo
      end


PM MAIL   Вверх
FCM
Дата 6.11.2010, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Цитата(TepH @  6.11.2010,  20:46 Найти цитируемый пост)
h=1/Nx

при целом Nx такое h дает ноль. Т.к. при целочисленном делении остаток отбрасывается.
Надо h = 1./Nx

Где тот там еще фигурирует 1/8 - замени на 1./8

Поиск максимума и минимума наверное можно в одном цикле сделать.

(В Фортране-90 есть стандартные функции поиска максимуиа и минимума массивов)

Это сообщение отредактировал(а) FCM - 6.11.2010, 21:28
PM MAIL   Вверх
TepH
Дата 6.11.2010, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.10.2010

Репутация: нет
Всего: нет



Спасибо. С точкой заработало. 
А MAX, MIN, MaxLoc, MinLoc, MinVal, MaxVal, которые, как я понимаю, для минимумов-максимумов, у меня всё время ошибку выдают. Видимо как-то неправильно записываю. Единственное, что скомпиллировалось:
Код

      Ma=MAXVal(y)

Но ответ неверный совсем выдаёт.
Поэтому я и сделал циклом.
MAX просит, по крайней мере, два аргумента 
MaxLoc просит массив. Уж не знаю, чем ему мой не понравился.
Если написать
Код

 k=MaxLoc(y)


То ошибку такую выдаёт:

Код

      k=MaxLoc(y)
      1
Error: Incompatible ranks 0 and 1 in assignment at (1)

Чего-то ему несовместимо...

Это сообщение отредактировал(а) TepH - 6.11.2010, 23:24
PM MAIL   Вверх
FCM
Дата 7.11.2010, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: 8
Всего: 9



Цитата(TepH @  6.11.2010,  23:10 Найти цитируемый пост)
То ошибку такую выдаёт:
Error: Incompatible ranks 0 and 1 in assignment at (1)
Чего-то ему несовместимо...


MINLOC в данном случае возвращает массив из одного элемента - поэтому проблема при присвоении скаляру.

В рамках Фортрана-90+ программа могла бы иметь вид
Код

      PROGRAM FUNC_TEST
      INTEGER :: NX
      REAL    :: H
      REAL, ALLOCATABLE :: X(:), Y(:)   ! Объявляем динамические массивы
 10   PRINT*, 'ENTER NUMBER OF STEPS (30-500)'
      READ*, NX
      IF( NX < 30 .OR. NX > 500 ) THEN
         PRINT*, 'ERROR. TRY AGAIN'
         GOTO 10
      ENDIF
      ALLOCATE( X(NX), Y(NX) )           ! Размещаем динамические массивы
      H = 1./(NX-1)
      DO I = 1, NX
         X(I) = I*H
         Y(I) = X(I)*(1-X(I))-1./8
      ENDDO
      PRINT*,  "Maximum of Y: ", MAXVAL(Y), "is achieved at X=" ,X(MAXLOC(Y))
      PRINT*,  "Minimum of Y: ", MINVAL(Y), "is achieved at X=" ,X(MINLOC(Y))
      DEALLOCATE(X,Y)                       ! Удаляем динамические массивы
      END


Возможно массив для X вводить необязательно, достаточно скаляра X
Код

      PROGRAM FUNC_TEST
      INTEGER :: NX
      REAL    :: H
      REAL, ALLOCATABLE :: Y(:)
 10   PRINT*, 'ENTER NUMBER OF STEPS (30-500)'
      READ*, NX
      IF( NX < 30 .OR. NX > 500 ) THEN
         PRINT*, 'ERROR. TRY AGAIN'
         GOTO 10
      ENDIF
      ALLOCATE( Y(NX) )
      H = 1./(NX-1)
      DO I = 1, NX
         X = I*H
         Y(I) = X*(1-X)-1./8
      ENDDO
      PRINT*,  "Maximum of Y: ", MAXVAL(Y), "is achieved at X=" , H*MAXLOC(Y)
      PRINT*,  "Minimum of Y: ", MINVAL(Y), "is achieved at X=" , H*MINLOC(Y)
      DEALLOCATE(Y)
      END


Это сообщение отредактировал(а) FCM - 7.11.2010, 14:59
PM MAIL   Вверх
AnyaPotehina
Дата 24.12.2010, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 24.12.2010

Репутация: нет
Всего: нет



5.6:
      SUBROUTINE para_range(1, n, nprocs, myrank, ista, iend)
     1
Error: Unclassifiable statement at (1)

что это за ошибка, подскажите, пожалуйста

PROGRAM main
      INCLUDE 'mpif.h'
      PARAMETER (n = 1000)
      DIMENSION a(n)
      SUBROUTINE para_range(1, n, nprocs, myrank, ista, iend)
      iwork = (n - 1)/nprocs + 1
      ista = MIN(myrank*iwork + 1, n + 1)
      iend = MIN(ista + iwork - 1, n)
      CALL MPI_INIT(ierr)
      CALL MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
      CALL para_range(1, n, nprocs, myrank, ista, iend)
      DO i = ista, iend
      a(i) = i
      ENDDO
      sum = 0.0
      DO i = ista, iend
      sum = sum + a(i)
      ENDDO
      CALL MPI_REDUCE(sum,ssum,1,MPI_REAL,
     & MPI_SUM, 0, MPI_COMM_WORLD, ierr)
      sum = ssum
      IF (myrank == 0) PRINT *,'sum=',sum
      CALL MPI_FINALIZE(ierr)
      END


программа считает сумму элементов массива a( )
она распараллелена, повторяющиеся операции распределены на блоки и каждый процесс вычисляет свою частичную сумму множества в вычисленном диапазоне с помощью подпрограммы para_range. Частичные суммы вконце суммируются MPI_REDUCE.

PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Fortran | Следующая тема »


 




[ Время генерации скрипта: 0.1084 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.