float bits and strict aliasing

后端 未结 4 1753
抹茶落季
抹茶落季 2020-12-01 09:29

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 = (unsign         


        
相关标签:
4条回答
  • 2020-12-01 09:52

    If you really want to be agnostic about the size of the float type and just return the raw bits, do something like this:

    void float_to_bytes(char *buffer, float f) {
        union {
            float x;
            char b[sizeof(float)];
        };
    
        x = f;
        memcpy(buffer, b, sizeof(float));
    }
    

    Then call it like so:

    float a = 12345.6789;
    char buffer[sizeof(float)];
    
    float_to_bytes(buffer, a);
    

    This technique will, of course, produce output specific to your machine's byte ordering.

    0 讨论(0)
  • 2020-12-01 09:54

    The following does not violate the aliasing rule, because it has no use of lvalues accessing different types anywhere

    template<typename B, typename A>
    B noalias_cast(A a) { 
      union N { 
        A a; 
        B b; 
        N(A a):a(a) { }
      };
      return N(a).b;
    }
    
    unsigned bar(float x) {
      return noalias_cast<unsigned>(x);
    }
    
    0 讨论(0)
  • 2020-12-01 09:57

    About the only way to truly avoid any issues is to 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 you are memcpying a fixed amount the compiler will optimise it out.

    That said the union method is VERY widely supported.

    0 讨论(0)
  • 2020-12-01 10:01

    The union hack is definitely undefined behavior, right?

    Yes and no. According to the standard, it is definitely undefined behavior. But it is such a commonly used trick that GCC and MSVC and as far as I know, every other popular compiler, explicitly guarantees that it is safe and will work as expected.

    0 讨论(0)
提交回复
热议问题