Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 浮点数相等性测试_Fortran_Mingw - Fatal编程技术网

Fortran 浮点数相等性测试

Fortran 浮点数相等性测试,fortran,mingw,Fortran,Mingw,我在Windows7(32位)下使用MinGW中的gfortran编译Fortran代码。以下是文件testequal.f中包含的最小代码: program testequal real*8 a1, a2 a1 = 0.3d0 a2 = 0.7d0 write(*,*) 1.d0 write(*,*) a1+a2 write(*,*) a1+a2.eq.1.0 write(*,*) a1+a2.e

我在Windows7(32位)下使用MinGW中的gfortran编译Fortran代码。以下是文件
testequal.f
中包含的最小代码:

      program testequal
      real*8 a1, a2

      a1 = 0.3d0
      a2 = 0.7d0

      write(*,*) 1.d0
      write(*,*) a1+a2
      write(*,*) a1+a2.eq.1.0
      write(*,*) a1+a2.eq.1.d0
      end
编撰

gfortran testequal.f -std=legacy
输出为:

1.0000000000000000
1.0000000000000000
F
F

但我认为这两个布尔值都是
T
(true)。这里有什么问题

除了极少数例外,不要比较浮点数是否完全相等。有限精度浮点运算的规则与实数运算的规则不同。将数字与公差进行比较,例如

sum = a1 + a2
if ( abs (sum - 1.0) < 1.0D-5 ) ...
sum=a1+a2
如果(abs(总和-1.0)<1.0D-5)。。。

真正的问题是0.3和0.7不能精确地用二进制表示。
0.3 => 0.010011001100110011....... 0.7=>0.10110011001100

在存储它们时,如果两个数字都向上舍入或向下舍入,则两个数字的相加将不会返回到1.000000000

这是编程模拟中的常见错误。尝试使用计算机自然的步长:

real*8 :: dt=2.0d0**(-5)
二的负幂可以在计算机中精确地表示出来。所以这实际上是可行的:

program negative_powers
  real*8 :: dt = 2.0d0**(-8)
  real*8 :: t = 0.0d0

  do while (t .ne. 500.0d0)
     print *, t
     t = t + dt
  end do
  print *, t
end program negative_powers

对实相的恰当比较应该是某种不可知论。这是一个比较的好方法:

if (abs(a1-a2) <= epsilon(a1)) print*, 'a1=a2'

if(abs(a1-a2)在Scientific Linux上使用
gfortran 4.4
两种方法我都得到了T。但是,我建议您可能应该花一些时间阅读。这有点偏颇,但数字1的表示完全不受影响,因此1.0和1.d0之间没有任何区别,甚至没有区别1@george当前位置我测试过了,你是对的。非常有趣。你可以吗你能给我一些这样的参考资料吗?谢谢!@KyleKanos:这看起来是一篇严肃的论文…维基页面有点容易阅读。只有直接输入数字,这才有效。但是如果你已经知道数字,你需要比较它们的可能性更小。大多数情况下,你比较一些结果,它们总是不准确的。我的想法是正确的经常使用类似的东西。这实际上取决于数字的含义和来源。如果它们是某种计算的结果,那么误差很容易大于机器ε,这是一个非常小的数字。有时我使用像
100*epsilon(…)
。有时人们可能会关心实际的
间距()
a1
a2
上。没有通用配方。同意。我的观点是,如果有通用配方,它会被实现为一个内在函数。在什么特殊情况下允许比较实数?比较没有做过数学运算的固定数应该是安全的,尤其是如果它们是e“真的”整数。赋值位置和测试位置的表示应该一致。这对于检测给定值是否为“默认值”(0.0,-999.0,或其他任何值)非常有用。但是,当你做数学运算时,所有的赌注都被取消了!