Is there an easy way to determine the sign of a floating point number?
I experimented and came up with this:
#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;
}
where (c[3] & 0x10000000) gives a value > 0 for a negative number but I think this requires me to make the assumptions that:
- The machine's bytes are 8 bits big
- a float point number is 4 bytes big?
- the machine's most significant bit is the left-most bit (endianness?)
Please correct me if any of those assumptions are wrong or if I have missed any.
1) sizeof(int) has nothing to do with it.
2) assuming CHAR_BIT == 8, yes.
3) we need MSB for that, but endianness affects only byte order, not bit order, so the bit we need to check is
c[0]&0x80
for big endianness, orc[3]&0x80
for little, so it would be better to declare union with anuint32_t
and checking with 0x80000000.This trick have sense only for non-special memory operands. Doing it to a
float
value that is in XMM or x87 register will be slower than direct approach. Also, it doesn't treat the special values like NaN or INF.I've got this from http://www.cs.uaf.edu/2008/fall/cs441/lecture/10_07_float.html try this:
Coming to this late, but I thought of another approach.
If you know your system uses IEEE754 floating-point format, but not how big the floating-point types are relative to the integer types, you could do something like this:
Essentially, you treat the bytes in your float as an unsigned integer type, then right-shift all but one of the bits (the sign bit) out of existence. '>>' works regardless of endianness so this bypasses that issue.
If it's possible to determine pre-execution which unsigned integer type is the same length as the floating point type, you could abbreviate this:
This worked on my test systems; anyone see any caveats or overlooked 'gotchas'?
Try
from
<math.h>
Another helpful thing may be #including
<ieee754.h>
, if it's available on your system/compiler.Why not
if (f < 0.0)
?Use signbit() from math.h.