我正在移植一些比较浮点数以处理64位 double 数而不是32位浮点数的代码,但是我对代码中使用的一些魔术数字感到有些困惑。
资料来源:http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
这是代码:
bool AlmostEqual2sComplement(float A, float B, int maxUlps)
{
// Make sure maxUlps is non-negative and small enough that the
// default NAN won't compare as equal to anything.
assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
int aInt = *(int*)&A;
// Make aInt lexicographically ordered as a twos-complement int
if (aInt < 0)
aInt = 0x80000000 - aInt;
// Make bInt lexicographically ordered as a twos-complement int
int bInt = *(int*)&B;
if (bInt < 0)
bInt = 0x80000000 - bInt;
int intDiff = abs(aInt - bInt);
if (intDiff <= maxUlps)
return true;
return false;
}
问题:
困扰我的主要是断言中的
4 * 1024 * 1024
号。这代表什么?对于64位双打,此值是什么?两者会一样吗?0x80000000
幻数也用作负零浮点数的int表示。所以我猜要64位 double ,这将不得不增加到0x8000000000000000
吗? 最佳答案
Ewww。
4 * 1024 * 1024是22位,比浮点数的显式尾数位少1。我认为两倍的等效值为2 ** 51。
您对0x800是正确的...此代码依赖于以下事实:可以比较IEEE浮点数,就好像它们是使用符号和幅度表示的整数一样。
当然,这段代码充满了不确定的行为。更不用说讨厌,野蛮和矮小了。