I was reading about Carmack's fast inverse square root algorithm and noticed this:
float x;
// ... //
int i = *(int*)&x;
Why would someone choose to use this weird type of casting instead of just the following?
int i = (int)x;
When the pointer is dereferenced, the indirection operator indicates that the value at the memory location stored in the pointer is to be accessed, rather than the address itself. Also note that this same character (*) is used as the multiplication operator. The compiler knows which operator to call, based on context.
Dereferencing is used to access or manipulate data contained in memory location pointed to by a pointer. *(asterisk) is used with pointer variable when dereferencing the pointer variable, it refers to variable being pointed, so this is called dereferencing of pointers.
That's different.
int i = (int) x;
will cast float
to int
, which will simply truncate it.
int i = *(int *) &x;
will load into i
the same bits that are currently stored in x
. The result is something totally different from truncating x
.
It's called type punning. It'll interpret the float
as an int
. Meaning, the bit representation is exactly copied.
It's a potentially dangerous operation, since some bit representations of floating point integers might be trap representations as integers (not the case with IEEE-754 floats and 2s complement integers, though).
Additionally, it might not work anymore, due to being undefined behaviour as per C standard. It's violating the strict aliasing rule.
C only supports accessing variable of a different type via memcpy
.
This is the valid standard C way of writing the operation:
int y; float x = 42.0f;
memcpy(&y, &x, sizeof(x));
C99 added another way of doing this, by using a union
:
union { int y; float x; } u = { .x = 42.0f };
int y = u.y;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With