Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Глюки в фортране 
:(
    Опции темы
Nutsy
Дата 29.9.2011, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Всем знатокам фортрана добрый день!

Я давно работаю на Ф. (уже лет 10), но все равно периодически натыкаюсь на совершенно непонятные вещи. Буду очень признательна всем, кто расскажет мне, от чего могут возникать подобные глюки.

1) результат вычислений зависит от промежуточного вывода. Т.е. считаю какую-то величину (как правило, интрегрированием) - получаю NAN. Вывожу промежуточные результаты, частичные суммы - получаю уже число, не NAN

2) печать данных - результат зависит от запроса. Т.е. от того, прошу ли я print *, d1, d2, d3 или print *, d3 (в одной и той же строке, просто комментируя или стирая лишние запросы) - я вижу разные величины для d3.

Пользуюсь линуксовским gfortran, обычно стараюсь не использовать оптимизацию. Раньше использовала другие компиляторы, но подобные проблемы периодически наблюдались вне зависимости от компилятора.

Всем заранее спасибо.
PM MAIL   Вверх
BakinEugene
  Дата 29.9.2011, 17:41 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

1) результат вычислений зависит от промежуточного вывода. Т.е. считаю какую-то величину (как правило, интрегрированием) - получаю NAN. Вывожу промежуточные результаты, частичные суммы - получаю уже число, не NAN

2) печать данных - результат зависит от запроса. Т.е. от того, прошу ли я print *, d1, d2, d3 или print *, d3 (в одной и той же строке, просто комментируя или стирая лишние запросы) - я вижу разные величины для d3.


Фантастика какая-то
Приведите пример программы.  smile 
PM MAIL WWW ICQ Jabber   Вверх
Nutsy
Дата 29.9.2011, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Пример не дам smile Во-первых, программы слишком большие, а во-вторых, это моя работа, не могу выкладывать на всеобщее обозрение. Могу сделать скрины двух последовательных запусков. Подойдет?

И, кроме того, это ничего не даст. Потому как в этом месте ошибки точно нет, и очевидно, что это не моя ошибка а реальный глюк.

Мне больше интересны именно такие же примеры у бывалых - откуда такое вообще берется, и как вообще с этим справляться.
PM MAIL   Вверх
Фантом
Дата 29.9.2011, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Конечно, хотелось бы посмотреть на примеры, однако один возможный вариант - не совсем корректный код, при оптимизации которого компилятор допускает ошибки.
Кстати, вместе с примерами хорошо было бы увидеть вывод и точную версию использовавшегося компилятора.

Добавлено через 14 минут и 39 секунд
Да, как вариант - попробуйте сменить компилятор и посмотреть, что получится.
PM   Вверх
Nutsy
Дата 30.9.2011, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо, я в общем и сама понимаю, что скорее всего это некорректный код. Просто когда имеется несколько десятков тысяч строк, хочется иметь подсказку - чего собственно искать-то?

Компилятор сменить проблематично, так как у меня нет админских прав, а по умолчанию стоит только один gfortran. 

Собственно, на данный момент проблему я обошла (но не решила). После замены команды gfortran на gfortran -O1 (т.е. включение оптимизации) проблема исчезла. Однако я понимаю, что та самая некорректность в коде никуда не делась, и она еще может вылезти потом - поэтому отловить хочется.

Это кусок кода:
http://s2.ipicture.ru/Gallery/Viewfull/6100499.html#
В зависимости от того, какая строка print закомментирована, получается следующий результат:

http://s2.ipicture.ru/Gallery/Viewfull/6100492.html#
Здесь видно два последовательных запуска скрипта main2.sh. Это мини-скрипт, который компилирует программу, а потом сразу запускает исполняемый файл.

Жду комментариев от мудрых, и всем заранее спасибо!   smile 

UPD: версия фортрана 4:4.5.2-1ubuntu3 (The GNU Fortran 95 compiler)

P.S. С картинками что-то не срослось, пришлось оставить их как ссылки.

Это сообщение отредактировал(а) Nutsy - 30.9.2011, 11:36
PM MAIL   Вверх
kemiisto
Дата 30.9.2011, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



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

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



Цитата(Nutsy @  30.9.2011,  10:31 Найти цитируемый пост)
Просто когда имеется несколько десятков тысяч строк, хочется иметь подсказку - чего собственно искать-то?

А чтоб дать подсказку, хочеться хотя бы одним глазком взнлянуть на десятки тысяч строк кода.

Цитата(Nutsy @  29.9.2011,  17:02 Найти цитируемый пост)
Пример не дам

Выход слева, в верхнем углу.

Цитата(Nutsy @  30.9.2011,  10:31 Найти цитируемый пост)
Это кусок кода

Судя по плотности оператора STOP...

Цитата(Nutsy @  30.9.2011,  10:31 Найти цитируемый пост)
Здесь видно два последовательных запуска скрипта main2.sh. Это мини-скрипт, который компилирует программу, а потом сразу запускает исполняемый файл.

Что конкретно я там должен увидеть? Что 2 программы, составленные из разных операторов вывода печатают разный результат? К.О. поперхнулся.

Цитата(Nutsy @  29.9.2011,  15:09 Найти цитируемый пост)
Я давно работаю на Ф. (уже лет 10)

Да, а я Ленина живым видел. Хотя... Вот Вы разве что работаете. А на нём программировать надо.

Это сообщение отредактировал(а) kemiisto - 30.9.2011, 11:56


--------------------
PM MAIL WWW GTalk Jabber   Вверх
Nutsy
Дата 30.9.2011, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



kemiisto, спасибо за полезный и содержательный ответ.
PM MAIL   Вверх
kemiisto
Дата 30.9.2011, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



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

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



Nutsy, всегда к Вашим услугам. smile 

Теперь попробуем по пунктам. Если Вы отказываетесь показывать исходный код (что бывает часто), нужно показать минимальный пример, на котором описанные "баги" проявятся. Тут, правда, надо в Вашем коде локализовать "баг", чего мы сделать за Вас не можем. Хотя бы потому, что код от нас скрыт.

Если локализовать сами не можете, а код показывать отказываетесь, то, чем, собственно, мы можем Вам помочь?


--------------------
PM MAIL WWW GTalk Jabber   Вверх
Фантом
Дата 30.9.2011, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



В принципе, я согласен с kemiisto - сказать что-то внятное по этому куску кода невозможно. Разве что одна деталь...

Я правильно понимаю, что весь код написан на 77-м Фортране? Если да: в нем используются COMMON-блоки и EQUIVALENCE? указывается ли стандарт языка при компиляции явно? почему в качестве компилятора не используется g77?
PM   Вверх
FCM
Дата 1.10.2011, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Nutsy @  30.9.2011,  11:31 Найти цитируемый пост)
Это кусок кода:
http://s2.ipicture.ru/Gallery/Viewfull/6100499.html#
В зависимости от того, какая строка print закомментирована, получается следующий результат:

http://s2.ipicture.ru/Gallery/Viewfull/6100492.html#
Здесь видно два последовательных запуска скрипта main2.sh. Это мини-скрипт, который компилирует программу, а потом сразу запускает исполняемый файл.


Что-то  там тяжело разобрать, что и где отличается. И насколько сильно отличается?
Напиши прямо здесь инструкции вывода  и результаты - может быть полезно, чтобы понять, насколько отличается. 
Еще интересно узнать
1) используется ли неявная типизация или, как рекомендуется, IMPLICIT NONE?
2) не смешиваются ли в выражениях типы с плавающей точкой разной точности?




Это сообщение отредактировал(а) FCM - 1.10.2011, 13:50
PM MAIL   Вверх
Nutsy
Дата 4.10.2011, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Для начала хотела поблагодарить всех за внимание к моей проблеме  smile 

Сразу поясню - к сожалению, Фортран мне преподавали на уровне простейших программок. Все остальное пришлось изучать самой, причем на старых чужих программах. Так что весьма вероятно, что мои знания малы и сумбурны.

Программа, с которой сейчас работаю, состоит из чужого кода (примерно 10тилетней давности), каких-то пакетов, стандартных процедур (типа диагонализации матриц), ну и конечно моего кода. Так ошибка может быть и не у меня  smile  

Теперь по вопросам. 

Попробую объяснить в чем была проблема: если я пишу 
print *, rho3
то на выходе вижу
1.010273778...
если в той же строчке, ничего кроме нее не меняя, дописываю еще одну переменную поглядеть
print *, rho1, rho3
вижу
1.000000010... 0.9999999989...
то есть второе выводимое значение (которое выводилось и раньше) почему-то меняется.

Собственно, программа была в процессе отладки, когда вот это нашлось. Тут даже не идет речь об ошибках или чем-то еще - это явный и очевидный глюк. И он явно не в этой конкретной строчке....


Фантом
Да, изначально использовался f77.  При компиляции ничего явно не указываю. Компилирую следующей командой:
gfortran -O1 -o main.out main.f o/*.f

Common-блоки использую очень и очень активно, без них вообще никак и никуда. Про equivalence слышу впервые - так что видимо не исользую.

FCM
Ответ конечно отличается не то чтобы сильно, где-то в 3-4 знаке. Проблема в том, что мне нужно больше, так как итоговый ответ складывается из нескольких чисел, и идет значительное сокращение (те же 3-4 знака). 

Неявная типизация используется. Обычно идет
implicit real*8 (a-h,o-y)
implicit complex*16 (z)
в этом куске кода правда обошлись без комплексных чисел.

Второй Ваш вопрос не очень поняла, отвечу как смогу. Все вещественные числа имеют одинаковую точность, а когда в выражениях фигурируют и вещественные, и целые - стараюсь менять тип, например, так
d = dsqrt(i*1.d0)

Какой будет диагноз?

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


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


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

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



Цитата(Nutsy @  4.10.2011,  11:29 Найти цитируемый пост)

Да, изначально использовался f77.  При компиляции ничего явно не указываю.


Вставьте ключ -ff2c при компиляции и посмотрите, что получится.
PM   Вверх
Nutsy
Дата 4.10.2011, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Фантом
Спасибо, попробую.

Мое видение проблемы на данный момент такое - где-то в коде (может, моем, может, предшественников) затесалась какая-то мелккая некорректность. Обычно компилятор ее проглатывает, но иногда не везет - и случается вот такой глюк. Отсюда вопрос: может, есть какой-нибудь очень-очень злой компилятор, который ругается на все что некорректно? Авось и нашлась бы тогда ошибочка...

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


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


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

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



Цитата(Nutsy @  4.10.2011,  14:34 Найти цитируемый пост)
Отсюда вопрос: может, есть какой-нибудь очень-очень злой компилятор, который ругается на все что некорректно?

Ну, для начала можно и gfortran сделать более строгим (включив все предупреждения). А из общедоступных компиляторов самый "жесткий", пожалуй, Sun'овский.
PM   Вверх
FCM
Дата 4.10.2011, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Nutsy @  4.10.2011,  11:29 Найти цитируемый пост)
Попробую объяснить в чем была проблема: если я пишу 
print *, rho3
то на выходе вижу
1.010273778...
если в той же строчке, ничего кроме нее не меняя, дописываю еще одну переменную поглядеть
print *, rho1, rho3
вижу
1.000000010... 0.9999999989...
то есть второе выводимое значение (которое выводилось и раньше) почему-то меняется.


А что будет, если написать
print *, rho3, rho1
или
print *, rho3, rho3
или
print *, rho3, rho1, rho3

Это сообщение отредактировал(а) FCM - 5.10.2011, 10:03
PM MAIL   Вверх
Nutsy
Дата 5.10.2011, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Фантом
Буду очень признательна если Вы напишете как это сделать, а то я в хелпе как-то не нашла...

FCM
Специально для Вас провела ряд экспериментов. Буду писать сначала кусочек кода, потом результат:

*******************
rho3 = rho
print *, rho 3

   1.0240488621215573    
*******************
rho3 = rho
print *, rho 3, rho

 -1.15385900643022870E+137 -1.15385900643022870E+137
*******************
rho3 = rho
print *, rho1, rho 3, rho

   1.0000000000000000        1.0107194919764675        1.0107194919764675 
*******************
rho3 = rho
print *, rho3, rho1, rho 3, rho

  1.0107194919764675        1.0000000000000000        1.0107194919764675        1.0107194919764675 
*******************
rho3 = rho
print *, rho3, rho1

 -1.15385900643022870E+137   1.0000000000000000    
*******************
rho3 = rho
print *, rho1, rho3

1.0000000000000000   -1.15385900643022870E+137     
*******************
rho3 = rho
print *, rho3, rho3

   1.0240488621215573        1.0240488621215573 
*******************

Т.е. результат не зависит от повторений, от порядка переменных, а только от их наличия. 

Ну как, нравится?  smile 


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


Опытный
**


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

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



Нравится. Но для полного счастья нужна подробная информация о rho - возможно проблемы именно в нем.

Это сообщение отредактировал(а) FCM - 5.10.2011, 17:51
PM MAIL   Вверх
Nutsy
Дата 5.10.2011, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



   real*8 function V(q)
    implicit real*8 (a-h,o-z)
    common /zn/Znucl
    common /screen/i_scr,iks,nwf_a,ka_a
    parameter (kMaxL = 9)
    parameter (NR1_g = 208)
    parameter (NR2_g = 2*(NR1_g+kMaxL))
    parameter (acl = 137.03599911d0)
    parameter (pi = 3.14159265358979323846)

    common /type_of_splines/type_of_splines
    common /wfgrid/break(NR1_g) /wfconst/nwfunc,na,kmax
    common /gaus/xx(64,13),cc(64,13) /Nst/Nstor(13)
    common /rn/rnucl
    common /inucl/inucl
    dimension r(0:114)
    dimension DI_B(0:10,0:10)

    do iii = 1,1                                             (это цикл включен для проверки в нескольких точках)
    q = 1.d-12 *10.d0**iii
    r_n = rnucl
    p = q
c    if (inucl.eq.1) then
c---------------------------c
c           Shell           c
c---------------------------c
          pr = q * r_n
          rho = dsin(pr) / pr
          rho1 = rho
c    elseif (inucl.eq.2) then
c---------------------------c
c           Sphere          c
c---------------------------c
    pr = q*r_n*dsqrt(5.d0/3.d0)
    if (pr.le.0.00001) then
    V1 = 1./3. - pr**2/30. + pr**4/840. - pr**6/45360.
    else
    V1 =  (dsin(pr)-pr*dcos(pr))/(pr)**3
     endif
    rho = V1*3.
    rho2 = rho
c    elseif (inucl.eq.3) then
c---------------------------c
c           Fermi           c
c---------------------------c
        ru_fermi = 52917.721d0 / 137.03599911d0
        af = 2.30d0 / 4d0 / dlog(3d0) / ru_fermi
        cf = dsqrt ( 5d0/3d0 * rnucl**2 - 7d0/3d0 * (pi*af)**2 )
    pac = pi * ac
    S_3_0 = S_k(-cf/af,3)
        S_5_0 = S_k(-cf/af,5)
    qf = 1d0 + pac**2 - 6d0 * ac**3 * S_3_0
          pc = q * cf
          pa = q * af
          spc = dsin(pc)
          cpc = dcos(pc)
          rho = 3.d0 * ( spc - pc * cpc ) / pc**3
          if (pc.lt.1d-5) then
            rho = 1.d0 - 0.1d0 * pc**2
          endif
          do m = 1, 1000
          tmp = 6d0 * ac**2 * (-1)**m / pc / ( m**2 + pa**2 )
     &        * ( ( m**2 - pa**2 ) / ( m**2 + pa**2 ) * spc + pc * cpc
     &            + m * pa / ( m**2 + pa**2 ) * dexp ( - m / ac ) )
            rho = rho - tmp 
          enddo
          rho = rho / qf
     rho3 = rho
     print *, rho3, rho3
c     print *, rho1, rho3, rho

        enddo
    stop

c    else
c    stop 'wrong nuclear model'
c     rho = 1.
c    endif
c    
    V = - Znucl/acl/q**2 * rho

    
 444    return
    end
c_____________________________________

PM MAIL   Вверх
kemiisto
Дата 5.10.2011, 18:48 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



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

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



Мне тут в чужом твитте довелось увидет дюже прелестный issue в одном баг-трекере. smile 

Говнокод настолько адский, что разбираться тут никто не будет. Видимо, даже компилятор не способен разобрать, что вы от него хотите. Единственное решение подсказано выше. smile 

IMPLICIT типизация, COMMON блоки, бросающиеся в глаза случаи некорректной арифметики с плавающей точкой (здесь parameter (pi = 3.14159265358979323846) точно должно быть d0 на конце), приправленные кодом из 70-х (фиксированный формат, великолепные названия переменных).

Хотя, даже интересно. smile Поковырять что-ли... gfortran, говорите...



--------------------
PM MAIL WWW GTalk Jabber   Вверх
kemiisto
Дата 5.10.2011, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



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

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



Фуф. smile Жесть. Вот чем хорошо модульное программирование, о котором, Вы, боюсь ничего не знаете, так тем, что модули (хорошо написанные, безусловно) можно тестировать изолированно. А тут... Ну выложили Вы этот кусок кода? И? Толку то?

Итак, я поубирал все COMMON блоки, повставлял фиктивных значений, для переменных, заданных этими блоками, покоментил чутка.
Код

      real*8 function V(q)
      implicit real*8 (a-h,o-z)
c      common /zn/Znucl
c      common /screen/i_scr,iks,nwf_a,ka_a
      parameter (kMaxL = 9)
      parameter (NR1_g = 208)
      parameter (NR2_g = 2*(NR1_g+kMaxL))
      parameter (acl = 137.03599911d0)
      parameter (pi = 3.14159265358979323846)

c      common /type_of_splines/type_of_splines
c      common /wfgrid/break(NR1_g) /wfconst/nwfunc,na,kmax
c      common /gaus/xx(64,13),cc(64,13) /Nst/Nstor(13)
c      common /rn/rnucl
c      common /inucl/inucl
      dimension r(0:114)
      dimension DI_B(0:10,0:10)

      rnucl = 1.0
      ac = 1.0

      do iii = 1,1
        q = 1.d-12 *10.d0**iii;
        r_n = rnucl
        p = q
c    if (inucl.eq.1) then
c---------------------------c
c           Shell           c
c---------------------------c
        pr = q * r_n
        rho = dsin(pr) / pr
        rho1 = rho
c    elseif (inucl.eq.2) then
c---------------------------c
c           Sphere          c
c---------------------------c
        pr = q*r_n*dsqrt(5.d0/3.d0)
        if (pr.le.0.00001) then
        V1 = 1./3. - pr**2/30. + pr**4/840. - pr**6/45360.
        else
        V1 =  (dsin(pr)-pr*dcos(pr))/(pr)**3
        endif
        rho = V1*3.
        rho2 = rho
c    elseif (inucl.eq.3) then
c---------------------------c
c           Fermi           c
c---------------------------c
        ru_fermi = 52917.721d0 / 137.03599911d0
        af = 2.30d0 / 4d0 / dlog(3d0) / ru_fermi
        cf = dsqrt ( 5d0/3d0 * rnucl**2 - 7d0/3d0 * (pi*af)**2 )
        pac = pi * ac
c        S_3_0 = S_k(-cf/af,3)
        S_3_0 = 1.0
c        S_5_0 = S_k(-cf/af,5)
        qf = 1d0 + pac**2 - 6d0 * ac**3 * S_3_0
        pc = q * cf
        pa = q * af
        spc = dsin(pc)
        cpc = dcos(pc)
        rho = 3.d0 * ( spc - pc * cpc ) / pc**3
        if (pc.lt.1d-5) then
          rho = 1.d0 - 0.1d0 * pc**2
        endif
        do m = 1, 1000
          tmp = 6d0 * ac**2 * (-1)**m / pc / ( m**2 + pa**2 )
     &        * ( ( m**2 - pa**2 ) / ( m**2 + pa**2 ) * spc + pc * cpc
     &            + m * pa / ( m**2 + pa**2 ) * dexp ( - m / ac ) )
          rho = rho - tmp
        enddo
        rho = rho / qf
        rho3 = rho
c        print *, rho, rho3
        print *, rho1, rho3, rho
      enddo
c      stop

c    else
c    stop 'wrong nuclear model'
c     rho = 1.
c    endif
c
c      V = - Znucl/acl/q**2 * rho


c 444    return
      end


У меня никакого "бага" при выводе естественно нет. Чтобы и в каком порядке я не выводил rho3 у меня всегда 2.2325875331982603. Просто "для галочки". 

Ещё раз - Вы несёте откровенную ахинею. Таких багов нет и быть не может.

Симптоматически можно предположить порчу памяти. НО! Если это "чистый" Fortran 77, то там, вроде никак не запортить. Однако исключать возможность использования всяких расширений (Cray Pointers) нельзя. Кроме того тут может быть ведь и Тандем. Не тот, который давече определился, а другой: сишечка + фортран. Но сразу после присвоения... Как-то с трудом верится.

Но код воняет. Не просто пахнет, воняет. Даже в этих 20 строчках кроме уже указанных недостатков, есть совершенно эпический цикл со счётчиком iii, где iii - число с плавающей точкой и оператор STOP, который не последний в теле функции. За такие вещи надо людей к стенке ставить...

Баг где-то есть. И не один, и не два. Их тонны в таком коде.


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


Опытный
**


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

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



Nutsy, попробуй, как уже отметил kemiisto, везде, где встречаются floating point- литералы (т.е. буквально заданные вещественные константы) добавить суффикс d0.
На будущее - никогда не пользуйся неявной типизацией - всегда ставь в начале любой программной единицы инструкцию  IMPLICIT NONE. При неявной типизации невозможно на этапе компиляции отследить опечатки в именах объектов данных в программе.


Это сообщение отредактировал(а) FCM - 6.10.2011, 11:32
PM MAIL   Вверх
Nutsy
Дата 6.10.2011, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



FCM
Спасибо за советы. Отказываться от неявной типизации, конечно, очень тяжко, но смысл этого действия вполне ясен. Про d0 тоже ясно, боюсь, тут мне нет оправданий - не ставила исключительно из-за лени. Может, будут еще какие-нибудь советы? Выслушаю внимательно и благодарно.

kemiisto
В Ваших сообщениях слишком много эмоций и слишком мало информации, чего можно ожидать скорее от человека, желающего самоутвердиться на форуме, чем от умного опытного програмиста, желающего помочь другим.  Я верю, что Вы очень умный и это получилось случайно как результат шока - поэтому не могли бы Вы написать поконкретнее?

Чем так плох код? (Не надо отвечать всем - это неинформативно)

Как названия переменных влияют на качество кода? Если есть какая-то связь, буду рада узнать - и тогда все исправлю. А то мне всегда казалось, что компьютеру все равно как что назвать, и это скорее для человека, а я свои названия понимаю хорошо - они все очень логичны (для меня). 

Чем можно заменить коммон блоки? Явная передача этих величин как параметров функции или подпрограммы невозможна.

Почему Вы решили что iii  - с плавающей точкой? Нам с компилятором казалось что оно вполне целое, где ошибка?

И что такого ужасного в операторе stop? Мне казалось, что для данной задачи (остановить исполнение кода на конкретном месте) он и придуман. Я не права? Есть альтернативы? В чем отличие альтернативных операторов от столь нелюбимого Вами? 

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

Это сообщение отредактировал(а) Nutsy - 6.10.2011, 14:37
PM MAIL   Вверх
kemiisto
Дата 6.10.2011, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



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

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



Цитата(Nutsy @  6.10.2011,  13:37 Найти цитируемый пост)
В Ваших сообщениях слишком много эмоций и слишком мало информации, чего можно ожидать скорее от человека, желающего самоутвердиться на форуме, чем от умного опытного програмиста, желающего помочь другим.

Вы так говорите, как будто в желании самоутвердится есть что-то плохое. smile А эмоции... Так они вообще и отличают нас от мерзких машин!

Цитата(Nutsy @  6.10.2011,  13:37 Найти цитируемый пост)
Чем так плох код?

Я писал уже.

Цитата(Nutsy @  6.10.2011,  13:37 Найти цитируемый пост)
Чем можно заменить коммон блоки?

Это надо смотреть, зачем они используются. Единого рецепта тут нет.

Цитата(Nutsy @  6.10.2011,  13:37 Найти цитируемый пост)
Явная передача этих величин как параметров функции или подпрограммы невозможна.

 smile Что значит "невозможна"? Почему?

Цитата(Nutsy @  6.10.2011,  13:37 Найти цитируемый пост)
Почему Вы решили что iii  - с плавающей точкой?

Потому что забыл латинский алфавит. smile 

Цитата(Nutsy @  6.10.2011,  13:37 Найти цитируемый пост)
Мне казалось, что для данной задачи (остановить исполнение кода на конкретном месте) он и придуман.

Такой задачи возникать не должно. Поэтому и оператор STOP не нужен.

Цитата(Nutsy @  6.10.2011,  13:37 Найти цитируемый пост)
а я свои названия понимаю хорошо - они все очень логичны (для меня)

Я уже писал по этому поводу. Если Вас всё в коде устраивает, тогда зачем Вы здесь?


--------------------
PM MAIL WWW GTalk Jabber   Вверх
FCM
Дата 6.10.2011, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Nutsy @  6.10.2011,  14:37 Найти цитируемый пост)
Про d0 тоже ясно, боюсь, тут мне нет оправданий - не ставила исключительно из-за лени. Может, будут еще какие-нибудь советы?

Сначала сделай с d0 и посмотри будут ли плавать соответствующие результаты.
Там еще в одном месте if (pr.le.0.00001) then
Вещественные числа обычно сравнивают только на строгое больше или меньше. 
PM MAIL   Вверх
bems
Дата 8.10.2011, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



Цитата(Nutsy @  6.10.2011,  14:37 Найти цитируемый пост)
Как названия переменных влияют на качество кода?
обоже...
Цитата(Nutsy @  6.10.2011,  14:37 Найти цитируемый пост)
Если есть какая-то связь, буду рада узнать

от них зависит читабельность. с именми навроде rho, rho1, V, V1 получается writeonly
Цитата(Nutsy @  6.10.2011,  14:37 Найти цитируемый пост)
А то мне всегда казалось, что компьютеру все равно как что назвать, и это скорее для человека, а я свои названия понимаю хорошо - они все очень логичны (для меня)
ну да, главное чтобы компилер да ты всё понимали smile
http://habrahabr.ru/blogs/htranslations/111348 пункт 2



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Nutsy
Дата 10.10.2011, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



FCM
Сделала в этом куске все с d0 и исправила сравнение как ты советовал. Не помогло. Теперь ползаю по всему коду, правлю d0 везде. Вернусь не скоро smile

bems
Я вообще-то пыталась вежливо намекнуть одному из советующих, что его советы не по делу. Кажется, не удалось... А что касается названий - большинство из переменных определенные физические величины, и им всегда сообветствует одна и та же буква (в данном случае - rho).  Так что назвать ее по-другому точно было бы усложнением себе жизни smile

Ссылка понравилась, спасибо smile Пункт 2 представить сложно - потому как у нас все программы исключительно для индивидуального пользования - но я постараюсь. Должно помочь smile

Еще вопрос для всех - а как же тогда правильно писать сложные выражения? Ну вот допустим, все что начинается с d - real*8, все что начинается с i - integer. Что из ниженаписанного правильно, а что нет?

dsum = d1 + 1.d0 + dble(i)
dsum = d2**i1
dsum = d2**d3

i1 = int(d1)
i2 = i1 + int (d1 + d2/d3 + d4**d5)

Надо ли всегда ставить dble  и int, или иногда в этом нет необходимости?

P.S. А может кто-то порекомендует ХОРОШУЮ книжку почитать?
PM MAIL   Вверх
FCM
Дата 11.10.2011, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Nutsy @  10.10.2011,  13:04 Найти цитируемый пост)
Надо ли всегда ставить dble  и int, или иногда в этом нет необходимости?

Не всегда. В ряде случаев работают неявные преобразования. Но нужно понимать, что "иногда" (когда речь идет "вещественных" числах разной точности) они дают не то, чтобы хотелось.
Например, 
Код

PROGRAM EXAMPLE
    IMPLICIT NONE
    REAL(8) :: X, Y
    X = 1./3. ;        WRITE(*,*)  X            !  0.33333334326744080
    Y = 1.D0/3. ;      WRITE(*,*)  Y            !  0.33333333333333331
END PROGRAM EXAMPLE 


 
Насчет книжки. Если интересует именно сохранение точности в вычислениях, можно посмотреть соответсвующий параграф ("Точность вычислений") в <Немнюгин, Стесик "Современный Фортран"2004>. Возможно и в других книгах или интернет-источниках этот вопрос обсуждается.


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


Новичок



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

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



FCM
Спасибо, смысл поняла. 
За рекомендацию книжки спасибо. Вы не поверите, но один из авторов и был моим преподавателем по Фортрану ;) 


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

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


 




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


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

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