C#-浮点比较函数说明
作者:互联网
有人愿意详细解释(逐个代码)这是做什么的吗?我已经阅读了布鲁斯·道森(Bruce Dawson)的关于比较浮子的论文,发现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 )?
}
解决方法:
布鲁斯·道森(Bruce Dawson)的论文全都有.浮点数(或双精度浮点数)的精度是有限的.这也意味着浮点数可以代表一组所有数字.
Dawson方法的作用是计算该集合中可以接受的“等值”步长,而不是使用固定的可接受误差值.一个这样的步骤的相对误差将随因子(几乎)变化2,其中,对于高的尾数值,相对误差较小,而对于低的尾数值,相对误差较大.但是,固定数量的步骤的相对误差变化不会超过此.
前往罗兰·伊利格(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)
您在计算机上得到的内容取决于实现.
标签:floating-point,c,net 来源: https://codeday.me/bug/20191208/2088213.html