2014-01-28 2 views
0

У меня возникла проблема, когда я использую функцию int(). У меня есть реальный массив mEL, и я хочу преобразовать некоторые его компоненты в целые числа для сравнения с реальным массивом COORDS. Я должен использовать int() из-за ошибок округления в COORDS массиве, поэтому ZERO не совсем ноль 3.D-77 или аналогичный:Функция int() в Fortran 77

 DO I = 1,nLines 
      IF (int(mEL(I,1)).EQ.int(COORDS(1,1)) .AND. 
1    int(mEL(I,2)).EQ.int(COORDS(2,1)) .AND. 
2    int(mEL(I,3)).EQ.int(COORDS(3,1))) THEN 

      .....do something 

Проблема в том, что во время бега исход int(COORDS(1,1)) изменений, но значение COORDS(1,1) является одна и та же. Например:

COORDS(1,1) = 1829.0000000 

В течение 1000 прогонов я получаю int(COORDS(1,1))=1829. Однако после некоторых пробегов я получаю: int(COORDS(1,1))=1828! но COORDS(1,1)=1829!

Любые идеи, почему это происходит?

+0

Вы действительно хотите иметь такую ​​большую приемлемую разницу между этими двумя значениями? –

+0

Нет, я не хочу. Вот почему я хочу этого избежать. Проблема в том, что int (COORDS (1,1)) иногда равен 1828, но COORDS (1,1) составляет 1829.0000, поэтому я ожидал, что int (COORDS (1,1)) будет 1829 ... – jpcgandre

+3

Well 'int' усекает, поэтому возможно, что если' coords (1,1) 'равно (приблизительно)' 1828.9999999999', тогда он будет отображаться (по некоторым параметрам форматирования) как '1829.0000000' или даже как' 1829', но усекать (правильно) до '1828'. Ничто из того, что вы нам сказали, исключает эту возможность. Является ли 'coords (1,1)' обновленным во время прогона? –

ответ

1

Введение в тему можно найти в разделе «Безопасные Сравнения» из статьи The Perils of Floating Point

Так что для вашего кода, вы можете использовать

 REAL EPS 
     PARAMETER (EPSILON = .000001) 

     DO I = 1,nLines 
      IF ((abs(mEL(I,1) - COORDS(1,1)) .LT. EPS) .AND. 
1   (abs(mEL(I,2) - COORDS(2,1)) .LT. EPS) .AND. 
2   (abs(mEL(I,3) - COORDS(3,1)) .LT. EPS)) THEN 

      .....do something 

      ENDIF 
     ENDDO 

Вы можете даже использовать что-то вроде abs(mEL(I,1) - COORDS(1,1)) .LT. (abs(mEL(I,1))* EPS) или abs(mEL(I,1) - COORDS(1,1)) .LT. (abs(mEL(I,1) + COORDS(1,1))* EPS), если вы хотите, чтобы относительная разница, а не абсолютная,

+0

Отличный ответ! – jpcgandre

Смежные вопросы