测试浮点数相等

时间:2013-12-24 17:52:04

标签: fortran mingw

我在Windows 7(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(真)。这里有什么问题?

3 个答案:

答案 0 :(得分:11)

除了极少数例外,不要将浮点数进行比较以确保完全相等。有限精度浮点运算的规则与实数运算的规则不一样。比较带有容差的数字,例如

sum = a1 + a2
if ( abs (sum - 1.0) < 1.0D-5 ) ...

答案 1 :(得分:2)

对于实际的正确比较应该是不可知的。这是比较的好方法:

IF

答案 2 :(得分:1)

真正的问题是0.3和0.7不能用二进制表示 0.3 =&gt; 0.010011001100110011 ....... 0.7 =&gt; 0.101100110011001100 .......

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

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

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

2的负幂可以在计算机中准确表示。所以这实际上会有效:

public int AllowedHorizontalSpace
{
    get { return this.allowedHorizontalSpace; }
    set
    {
        this.allowedHorizontalSpace = value;
        //                this.OnPropertyChanged(nameof(this.AllowedHorizontalSpace));
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("AllowedHorizontalSpace"));
    }
}