【问题标题】:int() function in Fortran 77Fortran 77 中的 int() 函数
【发布时间】:2014-01-29 15:51:17
【问题描述】:

我在使用int() 函数时遇到了一个问题。我有一个实数数组mEL,我想将它的一些组件转换为整数,以便与实数数组COORDS 进行比较。由于COORDS 数组中的舍入错误,我必须使用int(),所以ZERO 不是完全为零是3.D-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

你知道为什么会这样吗?

【问题讨论】:

  • 你真的是说这两个值之间有这么大的可接受差异吗?
  • 不,我不想要。这就是为什么我想避免它。问题是 int(COORDS(1,1)) 有时等于 1828 但 COORDS(1,1) 是 1829.0000,所以我期待 int(COORDS(1,1)) 是 1829...跨度>
  • 好吧,int 被截断,所以如果coords(1,1) 等于(大约)1828.9999999999,那么它会(在某些格式选项下)显示为1829.0000000,甚至显示为@987654339 @ 但截断(正确)为1828。你告诉我们的任何事情都没有排除这种可能性。 coords(1,1) 是否在运行期间更新?
  • 我会尝试使用NINT
  • 比较实数ab怎么样:if ( abs(a-b) < small ) ) then... ,其中small是一个合适的小值。

标签: int fortran


【解决方案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 ),如果你想要相对差异而不是绝对差异

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2010-10-18
    • 2015-08-08
    • 1970-01-01
    • 2013-06-27
    • 2023-03-27
    • 2016-12-15
    相关资源
    最近更新 更多