浮点比较函数说明

时间:2011-08-25 21:25:34

标签: c# .net floating-point

任何人都需要详细解释(代码代码)这是做什么的?我已经阅读了布鲁斯道森关于比较浮点数的论文并找到converted C# code of it,但不太明白。什么是maxDeltaBits及其目的?在Dawson的论文中,它指出这也可以应用于double,因此如果是这种情况,那么您需要将double值转换为Int64而不是int32

public static int FloatToInt32Bits( float f )
{
    return BitConverter.ToInt32( BitConverter.GetBytes( b ), 0 );
}

public static bool AlmostEqual2sComplement
    ( float a, float b, int maxDeltaBits )
{
    int aInt = FloatToInt32Bits( a );
    if ( aInt < 0 ) // Why only if it is less than 0?
        aInt = Int32.MinValue - aInt; // What is the purpose of this?

    int bInt = FloatToInt32Bits( b );
    if ( bInt < 0 ) // Why only if it is less than 0?
        bInt = Int32.MinValue - bInt; // What is the purpose of this?

    int intDiff = Math.Abs( aInt - bInt );
    return intDiff <= ( 1 << maxDeltaBits ); // Why ( 1 << maxDeltaBits )?
}

2 个答案:

答案 0 :(得分:2)

布鲁斯道森的论文就是这样。浮点(或双重)具有有限的精度。这也意味着浮点数可以表示一组所有数字。

道森的方法所做的,就是计算你可以接受的那个步骤多少步数,而不是使用固定的可接受误差值。一个这样的步骤的相对误差将随着因子(几乎)2而变化,其中对于尾数的高值,相对误差较小,对于尾数的低值,相对误差较大。但是,固定步数的相对误差变化不会更大。

To Roland Illig:

为什么“你永远不能直接测试两个FP数字的平等”这一事实?你可以,但你不会总是得到你期望的。存储为浮点数的不太大的整数将起作用。但是,可以写成有限数量的十进制数字的分数通常不能以有限数量的二进制数字存储。该号码将被截断。如果你做一些算术运算,那么截断引入的错误就会发挥作用。此外,机器的FPU可以存储具有更高精度的值,并且最终可以使用不等精度的值进行比较。

测试以下内容(C包括,更改为现代C ++的cstdio和cmath):

#include <stdio.h>
#include <math.h>

void Trig(float x, float y)
{
  if (cos(x) == cos(y)) printf("cos(%f) equal to cos(%f)\n",x,y);
  else printf("cos(%f) not equal to cos(%f)\n",x,y);
}

int main()
{
  float f = 0.1;
  f = f * 0.1 * 0.1 * 0.1;
  if (f == 0.0001f) printf("%f equals 0.0001\n",f);
  else printf("%f does not equal 0.0001\n",f);
  Trig(1.44,1.44);
  return 0;
}

在我的机器上,我在两种情况下都得到了“不相等”的分支:

0.000100 does not equal 0.0001
cos(1.440000) not equal to cos(1.440000)

您在计算机上获得的内容取决于实现。

答案 1 :(得分:1)

<0内容由http://en.wikipedia.org/wiki/Two%27s_complement引起。 maxDeltaBits处理的事实是你永远不能直接测试两个FP数是否相等,你只能确保它们在一定的精度范围内“几乎相同”。