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


Автор: Vander91 22.1.2011, 09:44
вот простая программа, выводящая числа от 1 до 10000, квадраты которых оканчиваются на 10001:

Код

program chislo
do 11 a=1,10000
if (a**2-10**5*floor(a**2/10**5).eq.10001) then 
print *,a
endif
11 continue
read*
end program chislo


на установленном Compaq Visual Fortran Professional v6.5 всё выводится нормально:

http://s012.radikal.ru/i319/1101/d6/f20a90625363.png

а в MS Visual Studio 2008 с установленным Intel Visual Fortran Compiler 11 ничего не выводится:

http://i068.radikal.ru/1101/1e/96fe276c8400.jpg

а почему?

Автор: FCM 22.1.2011, 14:53
В указанной программе тип переменной "a" неявно подразумевается REAL.
Возможно указанные компиляторы имеют разные настройки по операциям с REAL()-числами. 
Кроме того, проверять числа с плавающей точкой на точное равенство можно только "если очень хочется", т.е. не  рекомендуется. Возможно ситуация изменится, если использовать тип REAL(8), однако задача по сути "целочисленная".
Поэтому нужно
- либо изменить программу так, чтобы обойтись целыми числами. 
- либо проверку на прямое равенство REAL - чисел заменить на проверку достаточной малости их разности. 
причем первое предпочтительнее.

(Кроме того, некоторые компиляторы вообще непереваривают, если счетчик цикла - нецелый)
(И вообще - долой неявную типизацию и неблочную форму DO-цикла)

Автор: Vander91 23.1.2011, 17:05
всё ясно, спасибо, тут по умолчанию в записи чисел используется 8 знаков вместе с точкой, поэтому получалось 5001**2/10**5=250.1000 а не 250.10001

но ведь часто необходимо использовать очень большие числа, в том числе помнить много знаков после запятой.

предположим, слева от запятой мне нужно помнить 8 знаков, справа поле запятой тоже, не меньше: 12345678.12345678

каким образом задать это условие?

я плохо знаю фортран, помню в паскале было что-то подобное.

Автор: Фантом 23.1.2011, 17:26
Цитата(Vander91 @  23.1.2011,  17:05 Найти цитируемый пост)
слева от запятой мне нужно помнить 8 знаков, справа поле запятой тоже, не меньше: 12345678.12345678

Использовать тип real(8) (или больший, если позволяет компилятор). И лучше отказаться от использования архаичных средств сязыка (типизации по умолчанию, цикла с меткой, сравнения .eq. и т.п.).

Кстати, Ваша задача решается куда проще вообще без использования вещественного типа - достаточно использовать integer(8), в него поместится все необходимое.
Код

program chislo

  implicit none
  integer(8) :: a

  do a=1,10000
    if(modulo(a**2,100000)==10001) print *,a
  end do
  read *

end program chislo

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