# Pointers and Casting Pointers

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 10-16-2010
Eman
Pointers and Casting Pointers
Hi can anyone tell me whats the difference between this 2 statements?
Code:

```float num = 100.75 ; unsigned int a= *((unsigned int*)&num) ; //for this I am getting a value like 3247..and so on```
and this:
Code:

```float num = 100.75 ; unsigned int a = (unsigned int)num ; //I am getting 100```
why am I not getting the same result in a for both the statements?

Does casting the address to be of int type make it different or something?
I know that floating point numbers are stored differently in memory..
the decimal part and the fractional part are calculated separately then it is normalised..

so when I do that
and I cast the address to be of type unsigned int..
does it just take the binary and convert it to a decimal number so it can be stored in the unsigned int variable?

for the second statement why am I getting a 100 and not a number that looks random, i mean
the floating point number is stored in the same way so why will it just chop off the fractional part and print the decimal part..
is it because in the first statement i am actually trying to change how the floating point value is stored in memory?
thanks
• 10-16-2010
Salem
> Does casting the address to be of int type make it different or something?
Yes, it makes it wrong.

In the first instance, you just take a bunch of bits representing a float, and pretend they represent an unsigned int.

You can get the same effect by doing
Code:

```union {   unsigned int i;   float f; } v;```
Assign the value to v.f, and print v.i

In the second case, you perform a proper numeric conversion from one type to another, and you get the right answer.
• 10-16-2010
laserlight
The former reinterprets the binary representation of the float as that of an unsigned int. The latter converts the float to unsigned int, resulting in truncation.
• 10-16-2010
Eman
Quote:

Originally Posted by laserlight
The former reinterprets the binary representation of the float as that of an unsigned int. The latter converts the float to unsigned int, resulting in truncation.

So by specifying the address to be stored in a pointer of a different type..i am in effect creating a new value?

Is that not a bad thing? In what cases would I need to use this method?
• 10-16-2010
iMalc
Quote:

Originally Posted by Eman
So by specifying the address to be stored in a pointer of a different type..i am in effect creating a new value?

It doesn't actually create anything really. In fact in terms of the generated assembly it doesn't actually itself generate any code. You're simply telling it, hey see this memory address here, pretend it's a pointer to an int. Now, what is the value that my int pointer points to?

Quote:

Is that not a bad thing? In what cases would I need to use this method?
You would do that kind of thing if you were doing bit manipulation. A good case for it would be if you were writing a table-driven implementation of a 32-bit IEEE754 float to 16-bit IEEE754 half-float converter. (Which I just so happen to have already).
• 10-16-2010
laserlight
Quote:

Originally Posted by Eman
So by specifying the address to be stored in a pointer of a different type..i am in effect creating a new value?

It is not so much "creating a new value" as observing the value of the object (as in region of memory) as if it were an unsigned int.

Quote:

Originally Posted by Eman
In what cases would I need to use this method?

You might want to reinterpret some object as a bunch of bytes, but that should be quite rare. There are other applications involving void pointers, but again, that should be quite rare. Don't worry about it, and for the most part, don't do it.
• 10-16-2010
Eman
Quote:

Originally Posted by iMalc
It doesn't actually create anything really. In fact in terms of the generated assembly it doesn't actually itself generate any code. You're simply telling it, hey see this memory address here, pretend it's a pointer to an int. Now, what is the value that my int pointer points to?

You would do that kind of thing if you were doing bit manipulation. A good case for it would be if you were writing a table-driven implementation of a 32-bit IEEE754 float to 16-bit IEEE754 half-float converter. (Which I just so happen to have already).

Maybe creating is a bad word to use...
because the int pointer should point to an int, the binary representation of the floating point number was stored to an integer type format?

so lets say
100.75 is 0011
and i did the cast
Code:

` unsigned int a = *((unsigned int*)&num`
it will just take 0011 and convert it to 3?
so 3 now will be in a ... the numbers are just an example to understand what is happening in memory.

but if i did a simple
Code:

```float num = 100.7 int a = (int)num;```
it doesn't care about the binary representation and just
truncates the 0.7 part and stores 100 in a ..
sorry about the repetition. I am a slow learner and need to be able to visualise it.
Can you make your explanation simple? THanks
• 10-16-2010
laserlight
Quote:

Originally Posted by Eman
because the int pointer should point to an int, the binary representation of the floating point number was stored to an integer type format?

The binary representation of the floating point number was treated as if it was the binary representation of an integer.

Quote:

Originally Posted by Eman
it will just take 0011 and convert it to 3?

Yes, something like that.

Quote:

Originally Posted by Eman
it doesn't care about the binary representation

Not quite: the binary representation is needed to determine the value.

Quote:

Originally Posted by Eman
truncates the 0.7 part and stores 100 in a

Yes.
• 10-16-2010
Elysia
The thing is that whatever is stored in memory has no type. It's just a bunch of 1s and 0s.
In order to read and write something, the compiler stores those bits in a predetermined way. And then reads them back in the same way. But the compiler really have no idea what is actually stored in a given memory location. It relies on the type of your variable to know how to interpret the data stored there.
Now, floating points and integers are not stored the same way. So when you cast the pointer, you are essentially just telling the compiler: hey, there's an int stored there, so read it and store it in this variable. But a floating point is stored completely differently.
As an example, say, that we have 10.5. Let's say that in memory, it will look like: 1010 0101. The compiler would then read the first 4 bits and interpret this as the integer and the last 4 bits and interpret them as the decimal. But what happens if we tell the compiler it's an integer? The compiler reads all bits and interprets them as one big number and we get 165.

The second statement is different because you are telling the compiler: we have a float, and I want to convert it to an int. Thus, the compiler does the conversion for you and you get a real integer.

Hope this helps your understanding a little better.
• 10-16-2010
Eman
Quote:

Originally Posted by Elysia
The thing is that whatever is stored in memory has no type. It's just a bunch of 1s and 0s.
In order to read and write something, the compiler stores those bits in a predetermined way. And then reads them back in the same way. But the compiler really have no idea what is actually stored in a given memory location. It relies on the type of your variable to know how to interpret the data stored there.
Now, floating points and integers are not stored the same way. So when you cast the pointer, you are essentially just telling the compiler: hey, there's an int stored there, so read it and store it in this variable. But a floating point is stored completely differently.
As an example, say, that we have 10.5. Let's say that in memory, it will look like: 1010 0101. The compiler would then read the first 4 bits and interpret this as the integer and the last 4 bits and interpret them as the decimal. But what happens if we tell the compiler it's an integer? The compiler reads all bits and interprets them as one big number and we get 165.

The second statement is different because you are telling the compiler: we have a float, and I want to convert it to an int. Thus, the compiler does the conversion for you and you get a real integer.

Hope this helps your understanding a little better.

but one more question..
So whenever i am using a cast on an address to be stored in a different type (or any type) the binary is always interpreted to be stored as the typecast specified.
But if it is not a pointer cast (like casting a float to an int (float)num),
because it isn't casting (changing, inverting) the address it doesn't interpret the binary representation.

I am just trying to understand why in one scenario it interprets the binary representation and in other it merely truncates the values.

Is it because of casting the address, merely using a pointer?
• 10-16-2010
Elysia
Ah, but you must separate casts and dereferencing.
The pointer cast is done much the same as float -> int or vice versa. The float* is converted to a int* by the compiler. Since they're the same size and all (doesn't always hold true for all platforms), the conversion is trivial. That is, nothing really happens. The compiler just stores the old value in the new variable.
But when you dereference a pointer, then the magic happens. No conversion is done here.

So, to summarize:
Code:

```float x = 10.0f; int y = (int)x; int z = *(int*)&x;```
1) Compiler converts the float to an integer.
2) Compiler stores integer in y.

Second line:
1) Compiler converts the address of x from float* to int*. Conversion is trivial; the old value is just copied.
2) The compiler goes to the address pointed to by the pointer and reads the data.
3) The compiler stores the data in the variable.

So what would happen if we did
Code:

`float z = *(float*)&x;`
?

1) Compiler converts the address of x from float* to float*. Conversion is trivial; the old value is just copied.
2) The compiler goes to the address pointed to by the pointer and reads the data.
3) The compiler stores the data in the variable.

Essentially, only step 1 is altered. Do you see? The compiler simply relies on the type of pointer to know how to interpret the data. But since we change the pointer type, we also change how the compiler interprets the data. The data itself is never changed or converted, only the pointer type.
• 10-16-2010
whiteflags
Quote:

because it isn't casting (changing, inverting) the address it doesn't interpret the binary representation.
Typecasting always looks at the binary representation. Binary is the basic building block of everything the computer can store or do.

What is happening when you cast a float variable as an unsigned integer: You are taking the float's value and throwing away the fractional part. What is happening when you cast the float as an unsigned integer pointer and dereference that pointer: first the address of the float is taken and then given to a temporary integer pointer. That integer pointer is dereferenced, so you get the first half or so of the bits of the floating point number interpreted as an integer.

The bits of a real number may make sense as a whole number integer, but you are ignoring some of the bits so you have less information (wrong information).

If you merely did:

int num = whatever;
float mun = whatever;
num = mun;

The compiler would ........... Part of the reason casting is dangerous is because people think they're getting something they want out of it. It's almost always used superficially.
• 10-16-2010
Eman
so the difference between the changing the address and dereferencing it

Code:

```float x = 10.0f; int z = *(int*)&x;```
No conversion takes place. The compiler treats the dereferenced value as an int and stores it into z.

and simply using a typecast
Code:

``` int y = (int)x;```
while in this code the compiler does not treat the value of x as an int.
it just converts it to be an int and stores it in y, but the value of x would would remain intact.

For the value of x to remain intact I would imagine it uses some temporary memory location to store data while it is conversion.
• 10-16-2010
Elysia
You got it down pretty good.
But I'll just point out one thing:
There is a conversion taking place. That is, float* -> int* (address to address).
In the later, it's float -> int (floating point value to integer).
• 10-16-2010
Eman
Quote:

Originally Posted by Elysia
You got it down pretty good.
But I'll just point out one thing:
There is a conversion taking place. That is, float* -> int* (address to address).
In the later, it's float -> int (floating point value to integer).

yep i get ya :)
thank you dude..
thanks all
I have been struggling with this concept for a few days..now I understand what is happening.
Thanks, I appreciate it.
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last