我有一个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
答案 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
编辑:忘记添加以上的一个好处是编译器会警告我,如果我试图在使用错误的接口时比较两个不同类型的实数
编辑:已更新以使用便携式实数定义。