Арифметика с плавающей точкой в ​​Фортране - PullRequest
0 голосов
/ 05 июня 2018

Я унаследовал некоторый код на Фортране, который пытался понять.Он использует РЕАЛЬНЫЕ переменные во многих местах, что, я думаю, не должно - но, может быть, я неправильно понимаю, как это работает в Фортране (по сравнению с C ++, с которым я гораздо лучше знаком), отсюда и этот вопрос.

Таким образом, рассматриваемые переменные по сути являются «категориальными значениями», «факторами» или «перечислениями» в зависимости от того, как вы на это смотрите / хотите это назвать.Они имеют тип данных REAL и могут принимать только конечное число предварительно определенных целочисленных значений.Так, скажем, переменная a может иметь значение только 1, 2 или 3. Эти значения считываются из внешних файлов;в этих внешних файлах они представлены как целые числа, так что это не случай «проблем округления во внешних источниках данных» или чего-то подобного.

Однако в коде никогда не выполняется прямое сравнение, всегда большее, чем/ ниже, чем проверить.Таким образом, вместо

if (a == 1) then

он делает

if (a > 0.9 .and. a < 1.1) then

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

Так что я думаю, что это тот случай, когда кто-то в какой-то момент слышал «никогда не сравнивать РЕАЛЬНЫЕ значения» (из-за природы конечной точности хранения значений с плавающей запятой такая же проблема существует в каждом программированииязык), но потом не совсем понял, когда это применимо (я полагаю, первая ошибка заключается в том, что категориальные значения должны были быть представлены как целочисленные значения, но эта ситуация такая, какая она есть сейчас).

ОТОХ, может быть, яЯ просто неправильно понимаю, как значения REAL и INTEGER представлены и работают в Fortran?Может ли быть случай, когда

b = 1.5
a = REAL(INT(b))

if (a > 0.9 .and. a < 1.1) then

будет иметь смысл?

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Если по какой-то причине переменная должна оставаться РЕАЛЬНОЙ, вы можете использовать встроенную функцию Фортрана NINT (ближайшее целое число) в сравнениях:

if( nint(a) == 1 ) then 
....
0 голосов
/ 05 июня 2018

ТОЛЬКО в том случае, если вы не выполняете никаких операций с реальными значениями (просто присваиваете значение и сравниваете равенство с тем же самым литералом, который вы присвоили, с тем же параметром вида), вам не понадобится допуск.

Дело в том, что для реальной переменной, такой как:

Real a
a = 2

Вы можете быть уверены, что

a == 2

всегда будет .true..Но, например, для другого действительного значения, представленного b:

a  / b * b == 2

(или любой другой операции), гарантированно не будет .true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...