I am trying to convert a signed floating point variable to DWORD…the DWORD is to be used by another program so the DWORD variable type is important…
firstly…can a signed DWORD be interpreted as an unsigned DWORD..?
also…how can i convert a signed float to DWORD(signed)..?
DWORDis a 32-bit unsigned integer type defined by the Windows API. There is no such thing as a “signed DWORD”. Possibly you mean a corresponding signed type.In C++ all floating point types (
float,doubleandlong double) are signed types, so it’s unusual to talk about a “signed floating point”. Presumably you mean that it can be a negative value. And there are two main possibilities for converting a negative floating point values to unsigned integer:as if the floating point value, say
-1.23, is converted to signed integer, and then adjusted by a suitable multiple of 2n to bring it into the unsigned integer range, oras if the floating point value, again say
-1.23, is adjusted by a suitable multiple of 2n to bring it into the unsigned integer range, and then converted to the unsigned integer type.These procedures will generally yield different results, differing by 1. However, testing it, it’s the first procedure that’s used by Visual C++ 11.0 and MinGW g++ 4.7.1. And I suspect that somehow this is mandated by the standard (e.g., C++11 finally got clear rules about the result of integer division of negative numbers):
Output, with Visual C++ 11.0 and MinGW g++ 4.7.1:
Generally, the conversion (performed by simple assignment or initialization) loses data.
The compiler may warn about that. One possible way to make it shut up, which may or may not work, is then to use a
static_castto make the conversion explicit. Anyway, be aware that the conversion must lose data in the general case, because in general a floating point value has more bits than aDWORD.There is one case, however, where a
DWORDhas enough bits, and that’s for a value of typefloat, which in Windows is 32-bit IEEE.You can therefore represent any
floatvalue as aDWORDvalue with the same bits, but the connection between numerical values will then seem pretty arbitrary. And whether it will be practically useful depends on your other application. What does it expect, or what can it handle?Output, with Visual C++ 11 and g++ 4.7.1 (and indeed any practically useful Windows C++ compiler):
Note, however, that while this latter conversion is well defined in Windows, the Windows rule is not supported by the C++ standard. From a strictly formal point of view, inappropriately regarding the above code as platform-independent, the above breaks the strict aliasing rules of C++. Which g++ is very happy to inform you about:
In order to make silly compilers such as g++ happy, you have to do the conversion via a buffer of bytes. It’s pretty annoying, because the warning is all about the compiler detecting that what you have expressed that you want, is not compatible with some very undesirable marginal optimizations that it might apply. And when it can detect that it shouldn’t, why can’t it just not not do that undesirable thing, instead of warning about its inability to do it? Or, why can’t it just not not do it at all? Since nobody wants it.
But anyway, here’s code to make g++ shut up:
Of course, since it’s much more verbose and less efficient code, one may decide that shutting up a silly compiler (namely g++) is not worth it. Personally, I think it’s not worth it. Instead, just say
-fno-strict-aliasingto g++, and use thereinterpret_cast, because that’s what it’s for, why we have it in the language.Summing up, if your other program expects a numerical value that if possible is close to the original floating point value, then just convert to
DWORDby assigning or initializing, possibly using astatic_castto suppress compiler warnings.And if your other program expects the bits of a
floatvalue, then just use thereinterpret_castconversion. The code above shows how to use the more inefficient, verbose and bug-attractingmemcpyinstead just to please the g++ compiler. But my advice is, if that’s relevant, then just suppress the g++ warning via-fno-strict-aliasing(another useful such option to bring the g++ compiler into line with practicality, is-fwrapv, which IMHO should always be used).