我正在移植一些比较 float 的代码来处理 64 位 double 而不是 32 位 float ,但我对代码中使用的一些魔数(Magic Number)感到有点困惑。
来源: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 位 double 的值是什么?两者一样吗?
此外,0x80000000
魔数(Magic Number)也用作负零 float 的 int 表示。所以我猜测对于 64 位 double ,这必须增加到 0x8000000000000000
?
最佳答案
呃www。
4 * 1024 * 1024 是 22 位,比 float 的显式尾数位数少 1。我认为 double 的等价物是 2**51。
您对 0x800 的看法是正确的...此代码依赖于这样一个事实:IEEE float 可以像使用符号和大小表示的整数一样进行比较。
当然,这段代码充满了未定义的行为。更不用说肮脏、粗暴和短小了。
关于c++ - 移植比较 32 位 float 与 64 位 float 的代码,这个值代表什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20022174/