Search code examples
c++castingfloating-pointtype-punning

What happens when a pointer to a 32-bit integer is cast to a pointer to a float and dereferenced?


I saw this cast:

const std::uint32_t tmp = (some number);
float ToFloat = *(float*)(&tmp);

But when casting, the wrong number gets into the float. Moreover, if I use a static cast, then it is cast correctly.

  1. Why is this happening?
  2. How exactly does static_cast work?
  3. *(float*)(&Tmp) means that we are trying to dereference the pointer to the float, which is located at the address &tmp. Is it right?

Solution

  • Storing Integers

    Integers are stored in their binary (base 2) representation. int32_t occupies 32 bits.

    Storing Floats

    In most of the C++ compilers use a standard called IEEE 754, to store floats and doubles. Which differs a lot from how integers are stored.

    You can check how numbers are stored yourself using some sort of a IEEE-754 Floating Point Converter.

    Example

    Let us consider a simple example of number 5.

    const uint Tmp = 5;
    

    Tmp would be stored as 0x00000005 in memory, therefore &Tmp would point to the same.

    float ToFloat = *(float*)(&Tmp);
    

    Casting it into a float pointer would treat 0x00000005 to be in IEEE 754 format, having value 7.00649232162e-45.

    static_cast

    The static cast performs conversions between compatible types using safe implicit conversions.

    Note that you are converting from int* to float* in your question which is not a safe conversion. You can convert from int to float safely.

    const uint32_t Tmp = 5;
    float ToFloat = (float)Tmp; // 5
    

    More about static_cast conversion.