Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting to (int *) of (&num) when num is float in C

Why is the ouput of the following code : " i is: 1075838976"?

#include <stdio.h>

int main(){
  int i = 2;
  float num = 2.5;

  i = *((int *)& num);
  printf("i is: %d\n", i);
} 

Isn't it equivalent to :

#include <stdio.h>

int main(){
  int i = 2;
  float num = 2.5;

  i = num;
  printf("i is: %d\n", i);
} 

Which outputs : "i is 2"? Thanks.

like image 843
rok Avatar asked Dec 09 '22 14:12

rok


2 Answers

No, it's not equivalent at all.

This:

i = num;

converts the value of num (which is 2.5) from float to int. The conversion truncates the value to 2.

This:

i = *((int *)& num);

takes a pointer to the float object num, converts it to int*, and dereferences the resulting pointer.

If you're "lucky", this takes the bits making up the representation of num, pretends that they're the representation of an int, and gives you that results.

If you're not "lucky", then int and float may be of different sizes, a float object might be incorrectly aligned to be treated as an int object, or the result could even be a "trap representation" (though the latter is rare).

(I put "lucky" in quotation marks because, really, the best thing this code can do is blow up in your face, which immediately lets you know you're doing something questionable. The behavior is undefined, which means it's an error, but the implementation isn't required to warn you about it, either at compile time or at run time.)

The particular value you're getting, 1075838976, can be represented in hexadecimal as 0x40200000. If you look up the way float values are represented on your system, you can probably figure out how that bit pattern (0100 0000 0010 0000 0000 0000 0000 0000) makes up the the sign, mantissa, and exponent values that represent the value 2.5.

like image 187
Keith Thompson Avatar answered Dec 11 '22 10:12

Keith Thompson


In C "cast" is sort of "overloaded" and does two entirely different things:

-- Cause code to be generated to convert a "scalar" value between, say, int and float.

-- Coerce a pointer to a different type. This does not actually generate any code and does not convert anything.

((int *)& num) is coercing a pointer from float* to int*, and does not do any data conversion.

like image 22
Hot Licks Avatar answered Dec 11 '22 09:12

Hot Licks