浮点数的标志

Rar*_*rge 10 c++ floating-point signedness

有没有一种简单的方法来确定浮点数的符号?

我进行了实验并想出了这个:

#include <iostream>

int main(int argc, char** argv)
{
 union
 {
  float f;
  char c[4];
 };

 f = -0.0f;
 std::cout << (c[3] & 0x10000000) << "\n";

 std::cin.ignore();
 std::cin.get();
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

其中(c [3]&0x10000000)为负数给出的值> 0但我认为这要求我做出以下假设:

  • 机器的字节大8位
  • 一个浮点数是4个字节大吗?
  • 机器最重要的位是最左边的位(字节顺序?)

如果任何这些假设错误或者我错过了任何假设,请纠正我.

Jam*_*lis 10

假设它是一个有效的浮点数(而不是,例如,NaN):

float f;
bool is_negative = f < 0;
Run Code Online (Sandbox Code Playgroud)

它留给读者练习,以弄清楚如何测试浮点数是否为正.

  • 这在f = -0.0f的情况下不起作用; (18认同)
  • @Rarge:如果你依靠能够在点积计算之后区分"+ 0"和"-0",那么可以公平地说你有一个高度不稳定的算法吗? (3认同)
  • @Rarge:垂直点积将给出0的唯一情况是两个向量是平行的(或者考虑到浮点数学的限制而几乎无法区分).在这种情况下,期望"+ 0"和"-0"之间的差异是有意义的是不合理的. (3认同)
  • William Kahan的论文["Java的浮点如何伤害所有人"](http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf)包含一些引人注目的例子(例如来自流体力学),证明了为什么它很重要区分+0.0和-0.0.简而言之,除非区分+0.0和-0.0,否则它与复杂函数,分支剪切和无法保持的身份有关. (3认同)
  • @Jim:在深奥(并不是要淡化它们)的情况下,是的,这很重要.取两个向量的点积不是这些情况之一. (2认同)

Vla*_*lad 10

尝试

float s = copysign(1, f);
Run Code Online (Sandbox Code Playgroud)

<math.h>

另一个有用的东西可能是#including <ieee754.h>,如果它在您的系统/编译器上可用.

  • @Vlad:这只是将球门从"它绝对可用"转移到"它可能有用".请坚持@James提出的原始论点,即"它不是标准",你没有反驳.说实话,接受,然后继续前进.不要只是试着把它推到地毯下面. (2认同)
  • @GMan:这就是为什么我说"尝试"而不是"你可以实现这个".尽管是非标准的,但它得到了一些广泛使用的编译器的支持,因此可能对OP有所帮助.我们在这里帮助解决问题,而不是执行标准,对吧? (2认同)

ars*_*enm 9

使用math.h中的signbit().

  • `signbit()`不是当前C++标准库的一部分.它是提议的C++ 0x标准库的一部分(大多数 - 所有? - C99标准库是C++ 0x的一部分). (2认同)
  • @JamesMcNellis 现在使用 C++11,http://en.cppreference.com/w/cpp/numeric/math/signbit (2认同)