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.
- Why is this happening?
- How exactly does static_cast work?
*(float*)(&Tmp)
means that we are trying to dereference the pointer to the float, which is located at the address&tmp
. Is it right?
CodePudding user response:
Why is this happening?
The program has undefined behavior because you read from an int
through the eyes of a float
. This is not allowed in C .
How exactly does static_cast work?
In this case, it does the same conversion that float ToFloat = Tmp;
would do. That is, it converts the int
to float
and assigns it to ToFloat
.
*(float*)(&Tmp)
means that we are trying to dereference the pointer to the float, which is located at the address &Tmp. Is it right?
There is no float
at &Tmp
, only an int
. You however tell the compiler that the pointer is pointing at a float
and dereference that pointer. The bit patterns of int
s and float
s are very different so not only does it have undefined behavior, you will very unlikely get the correct result.
CodePudding user response:
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.