Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would someone use this type of cast in C? The reference of a float is cast to an int pointer and then dereferenced

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;
like image 409
user2445507 Avatar asked May 23 '16 05:05

user2445507


People also ask

When a pointer is dereferenced the value at the address stored in the pointer is retrieved?

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.

What does dereference mean in C?

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.


2 Answers

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.

like image 137
aragaer Avatar answered Oct 19 '22 12:10

aragaer


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;
like image 25
Leandros Avatar answered Oct 19 '22 12:10

Leandros