Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Fortran > FORTRAN: необычный GO TO


Автор: Pers_tmb 28.11.10, 19:19
Здравствуйте, уважаемые! :)

Вынужден переводить на понятный мне язык Си некоторую программку на фортране из книги, изданной в Лондоне аж в 1969 году. Фортран этот настолько бородат, что ни в одном русскоязычном учебнике я такого применения GO TO не увидел. Признаюсь, просматривал очень бегло.

Вот, собственно, код, вызвавший затруднение.

[ code ]

GO TO (1,2,1,1,1,1,1,1),K
1 SOURCE=0.
RETURN

2 SOURCE=A(I,J,NW)
RETURN
END

[ /code ]

Кто-нибудь знает, как это работает?

Автор: volvo877 28.11.10, 23:30
Нормальное использование, "вычислимый goto", если мне память не изменяет.

GO TO (список_меток), n
Сначала вычисляется выражение n, потом происходит переход к n-ой метке из списка. В твоем случае, только при K = 2 произойдет переход ко второй метке, при K = 1, или 3 .. 8 - переход к метке 1.

Автор: Pers_tmb 29.11.10, 08:24
Примерно так и предполагал, но надо было удостовериться.
Спасибо! :)

Автор: tulebaev 30.11.10, 08:25
Существует утилита Fortran2C (f2c) -- преобразует Fortran-код в C-листинг.

А самое быстрое -- скомпилировать Fortran-код в obj и подключить к проекту на C

Автор: Pers_tmb 09.12.10, 12:23
Я пробовал использовать f2c, но что-то не получилось. Думаю, надёжнее самому перевести код. Тут всего тысячи полторы-две строчек.. :)

Дабы не засорять раздел новой темой, задам вопрос тут.

Что значат записи вроде: I=0. и I=.0 ?

И самое интересное: WP(X12)=0.0*X12 ?

Автор: NetVir 09.12.10, 12:29
Цитата Pers_tmb @
I=0. и I=.0 ?
Присвоение вещественного нуля переменной.
Цитата Pers_tmb @
WP(X12)=0.0*X12
Забивается массив нулями, если X12 - это переменная цикла.

Автор: Pers_tmb 09.12.10, 12:36
Цитата
WP(X12)=0.0*X12

Я так полагаю, что это что-то вроде функции... потому что эта строчка соседствует с оными. Но просто смысла в такой функции нет.

Добавлено
Цитата NetVir @
Цитата Pers_tmb @
I=0. и I=.0 ?
Присвоение вещественного нуля переменной.

Иными словами, если на фортране написано I=5., то это float I=5, а если I=.5, то - float I=0.5?

Автор: NetVir 09.12.10, 12:39
Цитата Pers_tmb @
Иными словами, если на фортране написано I=5., то это float I=5, а если I=.5, то - float I=0.5?
да

Добавлено
Цитата Pers_tmb @
Но просто смысла в такой функции нет.
такое часто бывает. Я лично уже привык.

Добавлено
покажи описание переменной
Цитата Pers_tmb @
WP
и блок кода, где она учавствует

Автор: Pers_tmb 09.12.10, 12:48
В начале подпрограммы после описания глобальных переменных есть несколько строчек. Одна из них:

WP(X12)=0.0*X12

В коде же непосредственно есть строчка:

A(1,J,NW)=WP(X2(J))/R(J)

При этом, переменная X12 нигде не встречается.

Автор: NetVir 09.12.10, 12:52
в начале подпрограммы есть implicit none?

Автор: Pers_tmb 09.12.10, 13:00
Нет... сначала SUBROUTINE BOUNCT(K)
потом переменные COMMON
сразу после них вот эти "функции"... причём некоторые гораздо правдоподобнее выглядят: и входных значений побольше, и выражение внутри посложнее.

Перепечатывать все долго. С книги пишу.

Автор: NetVir 09.12.10, 13:20
Цитата Pers_tmb @
WP(X12)=0.0*X12
Это не функция. Это глупое забивание массива. ИМХО.
Что за книга?

Автор: Pers_tmb 09.12.10, 13:48
Госмен А.Д., Пан В.М., Ранчел А.К. "Численные методы исследования течений вязкой жидкости". В оригинале издана в 1969 ACADEMIC PRESS - LONDON AND NEW YORK. У нас - 1972 издательство "Мир".


Там рядом есть строчка WVW ( DELF,WQ,ROP,DELRO,ETA2 ) = -( DELF/((ETA*DX1)**2)+WQ*(ROP/6.+DELRO/8.))/(ROP/3.+5.*DELRO/24.). Сомневаюсь, что это массив.

Автор: andriano 09.12.10, 19:12
Цитата NetVir @
Цитата Pers_tmb @
WP(X12)=0.0*X12
Забивается массив нулями, если X12 - это переменная цикла.

Меня мучают смутные сомнения:
синтаксически - это присваивание X12-му элементу массива WP результата произведения "0.0" yf "X12". Смущает, правда, бессмысленность вычисления этого произведения.
Но, насколько я помню, присваивание значений всему массиву производится либо в заголовке оператором
DATA WP /0.0*X12/
либо в теле без указания индекса в скобках. Т.е. массив записывается как скалярная переменная. Ну еще есть всякие FORALL, но они синтаксически должны отличаться от присваивания элементу массива с заданным индексом.
В общем, хотелось бы видеть фрагмент кода побольше.

Автор: NetVir 09.12.10, 20:42
Цитата andriano @
синтаксически - это присваивание X12-му элементу массива WP результата произведения "0.0" yf "X12"
Так и есть (по идее).
Цитата andriano @
Смущает, правда, бессмысленность вычисления этого произведения.
Не должно так уж сильно смущать. Я и не такое видел. Как показывает практика, "великие мужи" хоть и великие в разрезе своего дела (области науки по своему профилю), но когда доходит дело до прикладного эксперимента (хоть и численного), то реализации оставляют желать лучшего, тем более, когда работы оформляются самими разработчиками численных методов. Обычно, такую работу перекладывают на плечи Ph.D. или чаще Ph.D. Candidate, которые уже более грамотно "прикладывают" работы своего начальства со знанием ЯП как минимум.

Добавлено
Цитата Pers_tmb @
Там рядом есть строчка WVW ( DELF,WQ,ROP,DELRO,ETA2 ) = -( DELF/((ETA*DX1)**2)+WQ*(ROP/6.+DELRO/8.))/(ROP/3.+5.*DELRO/24.). Сомневаюсь, что это массив.
И? В чем повод сомнения "WQ" - это не "WP".
Если найду книгу, то смогу дать более подробно консультацию.

Автор: NetVir 10.12.10, 11:50
Pers_tmb Книгу не нашел, поэтому по-сути трудно давать комментарии.

Автор: Pers_tmb 04.01.11, 16:50
Решив некоторые проблемы продолжаю заниматься переводом с фортрана на Си...

В подпрограмме подключаются глобальные массивы, объявляется ещё один большой массив и используется функция EQUIVALENCE.

Если выкинуть лишнее, код представляет из себя вот что:

[ code ]
COMMON/CVP/A(21,21,9),G1(21,21),G2(21,21),RO(21,21),ZMU(21,21)
DIMENSION AQ(21,21,14)
EQUVALENCE (A(1,1,1),AQ(1,1,1))
[/ code ]

Мне интересно, как связаны теперь массивы...
Если мы изменим A(1,1,1) изменится также AQ(1,1,1) и наоборот при изменении AQ(1,1,1) изменится ли A(1,1,1)?
И, если предыдущее предположение верно, что соответствует элементу AQ(1,1,10) - G1(1,1) или это ни с чем не связанный элемент?

Добавлено
Книга редкая. Наверняка издана небольшим тиражом в 1972 году...

Автор: NetVir 04.01.11, 22:11
Pers_tmb все описано с стандарте
Цитата
An EQUIVALENCE statement is used to specify the sharing of storage units by two or more entities in a program unit. This causes association of the entities that share the storage units.
Т.е. изменение A(1,1,1) влечет извенение AQ(1,1,1) и наоборот.
На счет COMMON: здесь другая ситуация - к A(21,21,9),G1(21,21),G2(21,21),RO(21,21),ZMU(21,21) можно одновременно обратиться через CVP, но изменение какого либо элемента из заданого перечисления не влечет за собой изменение всех остальных элементов из перечисления. Собсно
Цитата
The COMMON statement provides a means of associating entities in different program units. This allows different program units to define and reference the same data without using arguments, and to share storage units.

Автор: Pers_tmb 04.01.11, 23:50
Так, это понятно. И всё же массив G1 содержится в памяти следом за массивом A. При изменении элемента AQ(1,1,10) изменится ли элемент G1(1,1)?

Автор: amk 05.01.11, 14:12
COMMON в фортране кроме всего прочего гарантирует последовательное расположение своих элементов в памяти.
Поэтому (надо учесть, что в фортране быстрее всего меняются первые индексы, а в C - последние)
AQ(n,m,k) соответствует A(n,m,k) для 1 <= k <= 9
AQ(n,m,10) соответствует G1(n,m)
AQ(n,m,11) соответствует G2(n,m)
AQ(n,m,12) соответствует R0(n,m)
AQ(n,m,13) соответствует ZMU(n,m)
AQ(n,m,14) ничему не соответствует, возможно ошибка при подсчете индексов или в COMMON когда-то был еще один массив
везде 1 <= n, m <= 21

Поэтому ответ на последний ответ изменится, потому что это та же самая память

Автор: Pers_tmb 05.01.11, 17:28
Спасибо! :) Всё достаточно логично, но необходимо было переубедиться.

AQ(n,m,14) используется как вспомогательный массив.

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