【发布时间】:2017-10-18 13:42:06
【问题描述】:
我有一个 Fortran 程序可以测试两个浮点数的相等性。它可以浓缩为如下所示。当这个程序以“0.1”作为命令行参数运行时,我希望它打印“我所期望的”,而是打印“奇怪”。我知道这可能是由于浮点舍入问题造成的,但我希望有人能够准确解释我应该如何更改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
【问题讨论】:
-
我认为问题更多在于these lines,@HighPerformanceMark。答案是“将
inputvariable从real*8更改为real”或“将源代码中的0.1更改为0.1d0”(两者都需要注意real*8表示double precision)。 -
感谢您的意见。我计算出比较是 0.1 作为
real*4而不是real*8。我现在想知道的是,是否有任何方法可以测试real*4for 中的 0.1 和real*8形式中的 0.1 之间的相等性?似乎应该有某种方法来测试它们是否相等,但它们的精度并不相同。 -
经过进一步挖掘,似乎一般不建议测试浮点相等性。我会想办法用
.LE.改写代码。 -
问题是当用 real*4 和 real*8 表示时它们不是同一个数字,或者当用 real*8 表示不等于 0.1d0 时它们是 0.1。实际 *4 中的 0.1 是 0.1000000,而实际 *8 中是 0.100000000000000。请注意,real*8 有额外的零,当 real*4 提升为 real*8 进行比较时,计算机将用垃圾填充缺失的零,在我的机器上,real*8 中的 0.1 是 0.1000000001401161。通过写出一个带有双精度格式说明符的 real*4 来试试这个。
-
实际上,当从
REAL*4转换为REAL*8时,它将用零填充剩余的空间,而不是垃圾。但是,0.1 不能精确地表示为二进制,因此在REAL*8版本中它们不是零。尝试使用0.5或0.25或0.125,它们可以用二进制精确表示,你会发现.EQ.确实适用于它们。
标签: fortran