![]() |
|
![]() ![]() ![]() |
|
TepH |
|
|||
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 24.10.2010 Репутация: нет Всего: нет |
Помогите пожалуйста. Нужно написать программу, по которой можно узнать по введённым длинам сторон, существует такой треугольник или нет, а если существует, то какой он: равносторонний, равнобедренный, прямо-,остро-, тупоугольный.
Так вот, я написал, но при вводе длин 0,3; 0,4; 0,5 программа выдаёт, что треугольник остроугольный, хотя должен выдавать, что прямоугольный. Судя по всему, это происходит из-за погрешности преобразований чисел в двоичный код и обратно. Если посмотреть просто на умножение этих чисел, представляя числа, как double precision, получается, что, как я полагаю при возведении в квадрат числа, квадрат которого равен меньше 0,1 , он выдаёт такую бяку. В итоге для квадрата числа 0,3 получается что-то вроде 0,090000642. Из-за этого и происходит ошибка. Подскажите пожалуйста, как избавиться от этого? Вот текст мой программы:
|
|||
|
||||
FCM |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Сравнивать вещественные числа не есть хорошо в любом языке программирования (в некоторых C++ компиляторах даже предусмотрены предупреждения на сей счет).
Можно попробовать задать некий малый порог и сравнивать с ним модуль разности вещественных чисел. Кроме того, real лучше заменить на real(8). (И что за компилятор используется? В современных (в т.ч. бесплатных) компиляторах - максимум двух и более чисел можно найти с помощью функции max(a,b,c, ...). - операторы сравнения можно писать в естественной форме ==, >, < и т.п. - циклы лучше писать в так называемой блочной форме do...enddo. ) Это сообщение отредактировал(а) FCM - 24.10.2010, 19:23 |
|||
|
||||
TepH |
|
|||
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 24.10.2010 Репутация: нет Всего: нет |
Компиллятор... Даже и не знаю. Мы делаем через программу Putty. Через неё заходим на Unix-сервер и там делаем.
"Можно попробовать задать некий малый порог и сравнивать с ним модуль разности вещественных чисел." Знать бы как... Я ж сам не программист, а тут начали проходить Фортран лабораторными работами, а по обучалке читаем теорию. Но там нет такого(там много чего нету). Преподы говорят, что надо бы, чтобы мы сами додумались... |
|||
|
||||
Фантом |
|
|||
![]() Вы это прекратите! ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1516 Регистрация: 23.3.2008 Репутация: 5 Всего: 49 |
||||
|
||||
FCM |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
||||
|
||||
Фантом |
|
|||
![]() Вы это прекратите! ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1516 Регистрация: 23.3.2008 Репутация: 5 Всего: 49 |
||||
|
||||
FCM |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Программу можно построить по другому - введя подпрограмму сортировку (например так, чтобы a<=b<=c) чтобы не воодить s и не плодить if-ы
Это сообщение отредактировал(а) FCM - 25.10.2010, 14:02 |
|||
|
||||
TepH |
|
|||
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 24.10.2010 Репутация: нет Всего: нет |
||||
|
||||
FCM |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Потому что при введении eps надо согласовать все условия. Программу можно построить по другому - введя подпрограмму сортировки , чтобы не воодить s и не плодить if-ы
Выше - если используется f77, оператор > надо заменить на .gt. , а оператор < на .lt. - еще неидеально относительно выбора eps - возможно его лучше выбирать исходя из величины наиболее длинной стороны или т.п. - ну и надо проверить правильно ли работает сортировка Это сообщение отредактировал(а) FCM - 28.10.2010, 09:53 |
|||
|
||||
TepH |
|
|||
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 24.10.2010 Репутация: нет Всего: нет |
Что-то на вашу большую программу шибко ругается.
|
|||
|
||||
FCM |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Попробй еще раз (ранее была неточность в sort3):
В gfortran работает.
А если продолжает ругаться выложи весь код, на который ругается - может при копировании и вставке ошибки? Это сообщение отредактировал(а) FCM - 25.10.2010, 15:47 |
|||
|
||||
TepH |
|
|||
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 24.10.2010 Репутация: нет Всего: нет |
А теперь работает... Только тут такое дело, уж простите за то, что так гружу Вас, но если ввести, 1, 2, 3 то он пишет, что треугольник тупоугольный, а его, по-идее, не должно существовать (0н будет, так называемый, развёрнутый, т.е. прямая линия)... А в этой программе я даже не знаю, куда сунуться, чтобы это подправить. Что-то потыкался, а это вообще ничего не даёт.
А gfortran - это название компиллятора чтоли? |
|||
|
||||
FCM |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Вместо строки
лучше так (в предыдущем своем посте тоже поправил)
gfortran - фортран-компилятор из GCC-коллекции (может использоваться как в Linux, так и в Windows). Текщая версия GCC 4.5.x. Это сообщение отредактировал(а) FCM - 25.10.2010, 15:49 |
||||
|
|||||
FCM |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Возможно, для упрощения, в данном примере, для вводимых чисел можно снять сравнение с использованием порога eps , и оставить eps-проверку только в критических местах.
Будет примерно так:
Это сообщение отредактировал(а) FCM - 25.10.2010, 16:30 |
|||
|
||||
TepH |
|
|||
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 24.10.2010 Репутация: нет Всего: нет |
Хм. Заработало, вроде как... А я был близок к разгадке, когда искал, как подправить.
А, дошло. "a" всегда меньшее, "с" - большее. Поэтому в облегчённом и равенство а=в и в=с (правда бежать пора, потом посмотрю) Спасибо. Вы тут писали, пока, видимо, не исправили, что мне не стоит так, что я не знаю куда сунуться, раз учусь в техническом. Пожалуй Вы правы. Я в технаре учился, там, в общем-то железятник, хоть мы немного проходили qbasic и Turbo Pascal, но там как-то не так всё... И то, почти только ознакомительно. Поэтому довольно сложно не зная сразу программы писать, пусть и простейшие... |
|||
|
||||
FCM |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Если имеется в виду
то не поэтому. Просто из a==b и b==c следует a=c. Это сообщение отредактировал(а) FCM - 25.10.2010, 17:24 |
||||
|
|||||
TepH |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 24.10.2010 Репутация: нет Всего: нет |
Ну это я не туда глянул. Я имел в виду при сортировке, "а" становится меньшим, а "с" - бОльшим. и получается, что код действует:
Спасибо, вы мне очень помогли! Надеюсь, сегодня получится сдать. Только я никак не могу понять, что значит "0.d0" - 0,0*10 в степени 0?
и почему eps'у присваивается число 1.d-8, а не 1.e-8. В чём разница между d и e? Я пробовал менять, ничего не изменилось, вроде как.
|
||||||
|
|||||||
FCM |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Если в программе используется 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 |
|||
|
||||
TepH |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 24.10.2010 Репутация: нет Всего: нет |
Не сочтите за наглость, но я опять не справляюсь...
Так и знал, что со следующей тоже не справлюсь, лучше б про неё спросил... Наверное, я так буду думать с каждым последующим заданием... Но, я вс же надеюсь её сам выполнить. Поэтому не стал тему создавать ещё одну. Задание большое, делается подобными циклами, поэтому не должно бы быть особых трудностей. Но у меня не получается ввести массив, при выводе он всё по нулям выдаёт и соответственно, ни минимум, ни максимум не существует. Где-то я не так делаю в именовании массива, мне кажется. Надо сделать функцию из введённого количества элементов, найти минимум, максимум и номера максимального и минимального элементов, среднеквадратичные, ещё какие-то, относительное количество положительных и отрицательных элементов. Ну, там по формулам всё. Я пока только ввёл массив, и масксимум-минимум. Решил проверить, а ничего не работает, выдаёт нули... Я менял всё, что мне приходило в голову, но ничего, или ошибку выдаёт, или по нулям. Где параметр:
Я пробовал написать, к примеру:
|
||||||
|
|||||||
FCM |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
при целом Nx такое h дает ноль. Т.к. при целочисленном делении остаток отбрасывается. Надо h = 1./Nx Где тот там еще фигурирует 1/8 - замени на 1./8 Поиск максимума и минимума наверное можно в одном цикле сделать. (В Фортране-90 есть стандартные функции поиска максимуиа и минимума массивов) Это сообщение отредактировал(а) FCM - 6.11.2010, 21:28 |
|||
|
||||
TepH |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 24.10.2010 Репутация: нет Всего: нет |
Спасибо. С точкой заработало.
А MAX, MIN, MaxLoc, MinLoc, MinVal, MaxVal, которые, как я понимаю, для минимумов-максимумов, у меня всё время ошибку выдают. Видимо как-то неправильно записываю. Единственное, что скомпиллировалось:
Но ответ неверный совсем выдаёт. Поэтому я и сделал циклом. MAX просит, по крайней мере, два аргумента MaxLoc просит массив. Уж не знаю, чем ему мой не понравился. Если написать
То ошибку такую выдаёт:
Чего-то ему несовместимо... Это сообщение отредактировал(а) TepH - 6.11.2010, 23:24 |
||||||
|
|||||||
FCM |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
MINLOC в данном случае возвращает массив из одного элемента - поэтому проблема при присвоении скаляру. В рамках Фортрана-90+ программа могла бы иметь вид
Возможно массив для X вводить необязательно, достаточно скаляра X
Это сообщение отредактировал(а) FCM - 7.11.2010, 14:59 |
||||||
|
|||||||
AnyaPotehina |
|
|||
Новичок Профиль Группа: Участник Сообщений: 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. |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Fortran | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |