我正在移植一些比较浮点数的代码,以处理64位双倍,而不是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位翻倍,这将不得不增加到0x8000000000000000
发布于 2013-11-16 18:53:12
哇哦。
4* 1024 * 1024是22位,这比浮点数的显式尾数少一个。我想,双倍的等效值是2**51。
你是对的关于0x800..。这段代码所依赖的事实是,IEEE浮点数可以进行比较,就好像它们是使用符号和大小表示的整数一样。
当然,这段代码充满了无法定义的行为。更别提下流、野蛮和矮小了。
https://stackoverflow.com/questions/20022174
复制相似问题