c++ - float bits and strict aliasing -
i trying extract bits float without invoking undefined behavior. here first attempt:
unsigned foo(float x) { unsigned* u = (unsigned*)&x; return *u; }
as understand it, not guaranteed work due strict aliasing rules, right? work if take intermediate step character pointer?
unsigned bar(float x) { char* c = (char*)&x; unsigned* u = (unsigned*)c; return *u; }
or have extract 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 has disadvantage of depending on endianness, live that.
the union hack undefined behavior, right?
unsigned uni(float x) { union { float f; unsigned u; }; f = x; return u; }
just completeness, here reference version of foo
. undefined behavior, right?
unsigned ref(float x) { return (unsigned&)x; }
so, possible extract bits float (assuming both 32 bits wide, of course)?
edit: , here memcpy
version proposed goz. since many compilers not support static_assert
yet, have replaced static_assert
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; }
about way avoid issues memcpy.
unsigned int floattoint( float f ) { static_assert( sizeof( float ) == sizeof( unsigned int ), "sizes must match" ); unsigned int ret; memcpy( &ret, &f, sizeof( float ) ); return ret; }
because memcpying fixed amount compiler optimise out.
that said union method supported.
Comments
Post a Comment