Я пытаюсь использовать внутреннюю функцию «ПОТОЛОК», но ошибка округления затрудняет получение того, что я хочу иногда. Пример кода просто очень прост:Используйте ПОТОЛОК без эффекта округления Ошибка
PROGRAM MAIN
IMPLICIT NONE
INTEGER, PARAMETER :: ppm_kind_double = KIND(1.0D0)
REAL(ppm_kind_double) :: before,after,dx
before = -0.112
dx = 0.008
after = CEILING(before/dx)
WRITE(*,*) before, dx, before/dx, after
END
значение я даю «до» и «ах» в коде только для демонстрации. Например, для тех, кто до/dx = -13.5, я хочу использовать ПОТОЛОК для получения -13. Но для картины, которую я показываю, я действительно хочу получить -14. Я рассмотрел некоторые аргументы, такие как
IF(ABS(NINT(before/dx) - before/dx) < 0.001)
Но это просто не красиво. Есть ли лучший способ сделать это?
Update:
я с удивлением обнаружил, что проблема не будет возникать, если я установить переменные константы в ppm_kind_double. Поэтому я предполагаю, что эта «ошибка округления» произойдет только тогда, когда число цифр для точности округления машины, которую я использую, больше, чем указано в ppm_kind_double. Я фактически запускаю свою программу (не этот демонстрационный код) в кластере, чего я не знаю о точности машины. Так может быть, это четкость на этой машине, что приводит к этой проблеме?
После того как я установить константы двойной точности:
before = -0.112_ppm_kind_double
dx = 0.008_ppm_kind_double
Вы отбросили меня с желанием -14. Потребовалось некоторое время, чтобы понять, что -0.112/0.008 ровно -14, но из-за ошибок округления результат несколько больше, а «ПОТОЛОК» затем усиливает эту минусовую ошибку. – chw21
@ chw21, на самом деле я видел ваш предыдущий комментарий и ждал, пока вы его найдете. :) – Ruizhi
Данная точность является частью проблемы здесь, стоит отметить, что ваши литеральные константы являются единственной точностью - например, '-0.112' должно быть написано' -0.112_ppm_kind_double'. Однако это изменение не решит основной проблемы. – IanH