检测在C ++中存储为double的负0

时间:2011-04-01 17:23:43

标签: c++ double ieee-754

我正在进行一些数学计算(尝试使用VS2010将Matlab代码转换为C ++),我需要能够判断在某些时候我得到的是负数0.

根据IEEE标准-0 / + 0仅在符号位上有所不同(其余为0)。

我使用了以下代码(post)将我的double解释为unsigned char

double f = -5;
    unsigned char *c = reinterpret_cast<unsigned char *>(&f);
    for(int i=(sizeof(double)-1); i>=0; i--){
        printf("%02X", c[i]);
   }

尝试使用5 / -5我得到了预期的结果:

C014000000000000 (-5)
4014000000000000 (5)

但是当我用0 / -0尝试它时,我在这两种情况下都只得到零。 VS2010声称它们符合IEEE标准(msdn)所以我不确定它的哪一部分我没有得到。

如果0 / -0确实以完全相同的方式存储在内存中,我无法分辨它是否需要,所以我应该停止浪费时间:)对吗?

3 个答案:

答案 0 :(得分:24)

如果你写

double d = -0; 

将发生以下情况:

首先,将评估-0,其类型为int,因为0的类型为int。结果将为0.然后0将转换为double,因此分配为+0.0,而不是-0.0

double d = -0.0; // is your solution.

答案 1 :(得分:18)

除了亚美尼亚的好答案,你应该使用signbit来检测这一点。这样做可以保护您免受端序问题的影响:

#include <iostream>
#include <cmath>

int main()
{
    std::cout << std::signbit(0.0) << '\n';
    std::cout << std::signbit(-0.0) << '\n';
}

0
1

答案 2 :(得分:0)

将相同类型的函数重写为更短的形式:

static inline unsigned bool signbit(double& d)
{
    return ( ((unsigned char*)&d)[sizeof(double)-1] & 0x80) != 0;
}


int EstimateDoubleBufferSize( double& d )
{
    int len = 0;

    if( signbit(d) ) //if ( d < 0 )
    {
        d = -d;
        len++;
    }
    d += 0.0000005;

    int m = (int) log10(d);

    if( m < 0 )
        m = 1;  // 0.xxxx - include 0
    else
        m++;    // Include first character

    len += m + 1 /*dot*/ + 6 /* precision after . */;
    return len;
}

此外,我还需要弄清楚microsoft c ++编译器sprintf大小 - 包含的功能。