Fortran浮点平等

时间:2017-05-18 16:11:08

标签: fortran

我有一个Fortran程序,用于测试两个浮点数中的相等性。它可以浓缩为如下所示。使用" 0.1"运行此程序时作为命令行参数给出,我希望它能打印出我预期的#34;但相反,它打印"奇怪"。我知道这可能是由于浮点舍入问题,但我希望有人能够准确地解释我应该如何更改inputvariable以使此代码打印"我的期望"使用命令行参数0.1

program equalitytest
  character(len=3) :: arg1
  real*8           :: inputvariable
  CALL GET_COMMAND_ARGUMENT(1,arg1)
  READ(arg1,*) inputvariable
  IF (inputvariable.EQ.0.1) THEN
    PRINT*, "what I expected"
  ELSE
    PRINT*, "strange"
  ENDIF
end program equalitytest

运行如下:

./equalitytest 0.1
strange

1 个答案:

答案 0 :(得分:1)

总的来说,为什么人们需要将平等与实数进行比较的原因应该很少。如果我发现自己编写了这样的代码,我倾向于停下来思考一下我想要实现的目标。实际情况究竟是什么反映了这一点?

上面的例外与零相关,要么是在写入检查和处理可能的除法的鲁棒代码,要么是在搜索方程的收敛解的情况下 - 在后一种情况下,应该考虑使用三角洲无论如何。

如果确实需要此检查,为什么不将其外包给项目中的标准库,例如

module mylib
    use iso_fortran_env

    implicit none
    private

    public :: isReal4EqualReal4
    public :: isReal4EqualReal8
    public :: isReal8EqualReal4
    public :: isReal8EqualReal8

    real(real32), parameter :: delta4 = 0.001
    real(real64), parameter :: delta8 = 0.0000000001

    contains

        logical function isReal4EqualReal4(lhs, rhs) result(equal)
            real(real32), intent(in) :: lhs
            real(real32), intent(in) :: rhs
            equal = (abs(lhs - rhs) .le. delta4)
        end function isReal4EqualReal4

        logical function isReal4EqualReal8(lhs, rhs) result(equal)
            real(real32), intent(in) :: lhs
            real(real64), intent(in) :: rhs
            equal = (abs(lhs - real(rhs,4)) .le. delta4)
        end function isReal4EqualReal8

        logical function isReal8EqualReal4(lhs, rhs) result(equal)
            real(real64), intent(in) :: lhs
            real(real32), intent(in) :: rhs
            equal = isReal4EqualReal8(rhs, lhs)
        end function isReal8EqualReal4

        logical function isReal8EqualReal8(lhs, rhs) result(equal)
            real(real64), intent(in) :: lhs
            real(real64), intent(in) :: rhs
            equal = (dabs(lhs - rhs) .le. delta8)
        end function isReal8EqualReal8

end module mylib

编辑:忘记添加以上的一个好处是编译器会警告我,如果我试图在使用错误的接口时比较两个不同类型的实数

编辑:已更新以使用便携式实数定义。