KnowledgeHub
Questions
Tags
Users
Search
Alex Rivera
|
Logout
Edit Question
Title
Body
I am trying to extract the bits from a float without invoking undefined behavior. Here is my first attempt: unsigned foo(float x) { unsigned* u = (unsigned*)&x; return *u; } As I understand it, this is not guaranteed to work due to strict aliasing rules, right? Does it work if a take an intermediate step with a character pointer? unsigned bar(float x) { char* c = (char*)&x; unsigned* u = (unsigned*)c; return *u; } Or do I have to extract the individual bytes myself? unsigned baz(float x) { unsigned char* c = (unsigned char*)&x; return c[0] | c[1] << 8 | c[2] << 16 | c[3] << 24; } Of course this has the disadvantage of depending on endianness, but I could live with that. The union hack is definitely undefined behavior, right? unsigned uni(float x) { union { float f; unsigned u; }; f = x; return u; } Just for completeness, here is a reference version of foo . Also undefined behavior, right? unsigned ref(float x) { return (unsigned&)x; } So, is it possible to extract the bits from a float ( assuming both are 32 bits wide , of course)? EDIT: And here is the memcpy version as proposed by Goz. Since many compilers do not support static_assert yet, I have replaced static_assert with some template metaprogramming: template <bool, typename T> struct requirement; template <typename T> struct requirement<true, T> { typedef T type; }; unsigned bits(float x) { requirement<sizeof(unsigned)==sizeof(float), unsigned>::type u; memcpy(&u, &x, sizeof u); return u; }
Tags (comma-separated)
Save Edits
Cancel