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

vic*_*y5G 19 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]);
   }
Run Code Online (Sandbox Code Playgroud)

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

C014000000000000 (-5)
4014000000000000 (5)
Run Code Online (Sandbox Code Playgroud)

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

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

Arm*_*yan 24

如果你写

double d = -0; 
Run Code Online (Sandbox Code Playgroud)

以下将发生:

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

double d = -0.0; // is your solution.
Run Code Online (Sandbox Code Playgroud)

  • @Eamonn:我不相信它是标准的.无论如何,-0.0"直接读作双". (5认同)
  • 或者你也可以这样做:double d = -0D; 这告诉编译器直接读取它为双:) (3认同)
  • 提示:即使是`-0.(注意到最后的点)也被视为"双重". (2认同)
  • ......以及`-.0`.下一步将是`-`,但遗憾的是,它不是表示浮点零的有效方法. (2认同)

How*_*ant 18

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

#include <iostream>
#include <cmath>

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

0
1
Run Code Online (Sandbox Code Playgroud)