【问题标题】:Porting code that compares 32bit floats to use 64bit, what does this value represent?移植比较 32 位浮点数以使用 64 位的代码,这个值代表什么?
【发布时间】:2013-11-30 02:11:35
【问题描述】:

我正在移植一些比较浮点数以处理 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

【问题讨论】:

    标签: c++ floating-point floating-point-precision


    【解决方案1】:

    Ewww。

    4 * 1024 * 1024 是 22 位,比浮点数的显式尾数位数少 1。我认为 double 的等价物是 2**51。

    你对 0x800 是正确的...此代码依赖于这样一个事实,即 IEEE 浮点数可以像使用符号和大小表示的整数一样进行比较,主要是。

    当然,这段代码充满了可怕的未定义行为。更不用说肮脏、野蛮和简短。

    【讨论】:

    • 2**51 == 0x8000000000000?此外,我不是 C++ 的忠实粉丝,我将其移植到 D 中,其中不存在这种未定义的行为废话。 :)
    • 不知道,在第 7 个 0 之后计数丢失。即使您修复了字节顺序并需要 IEEE754,将 double 重新解释为 int 也是个坏消息。
    • 我不会将 double 重新解释为 int。
    • 是的,这就是*(int*)&amp;A 所做的,以及整个功能所依赖的。 (假设您已按照您所说的将 float 更改为 double。)
    猜你喜欢
    • 2010-12-01
    • 1970-01-01
    • 2011-01-24
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 2011-01-16
    • 1970-01-01
    相关资源
    最近更新 更多