# What is happening here please explain

• 09-23-2008
jayee_spicyguy
What is happening here please explain
signed int x,y,z;

x = (int) (((long)y * z) /100);
/* if i gave y = 8000 and z = 1100 iam getting x as -1 instead of 22464*/
• 09-23-2008
laserlight
Quote:

if i gave y = 8000 and z = 1100 iam getting x as -1 instead of 22464
How in the world can you get 22464 in the first place? Mathematically, the result should be 88000.

Oh wait, you are expecting an overflow, and sizeof(int) is 2 on your machine?

EDIT:
Right, here's the relevant text from C99:
Quote:

Originally Posted by C99 section 6.3.1.3
When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

Now, 88000 is always in the range of a long. It may not be in the range of an int, since int is only guaranteed a maximum value of at least 32767. Therefore the third paragraph holds, the result is implementation defined, and -1 is what your implementation defined.
• 09-23-2008
C_ntua
Here is what I tried in a 32bit CPU:
Code:

```#include <stdio.h> #include <stdlib.h> int main(void) {         signed short x,y,z;         y = 8000; z=1100;         x = (short)(((int)y * z) / 100);         printf("&#37;d", x);         return 0; }```
Compiled with: gcc -std=gnu99 and without -std=gnu99 and got:
Output: 22464

That is expected though, since I use short and what the text from C99 refers to is only for int.

Lets see what happens when we remove the casting. If you remove the (short) you get the same result, since gcc doesn't even yield a warning. If you remove the (int) then again you get the same result. That makes me assume that the x*y calculation is saved into a 32bit register. So it holds the correct value. If it was hold in a 16bit register (or half register) then you would get a different result.
That is why I believe when it is bigger than an int the value is defined somehow. Because the overflow would not make any sense and it could be more or less undefined. If it not an int though, as in my example, I can guess, as you did, the result. And that makes sense and might be useful in a program, since the overflow can be helpful sometimes.

EDIT: What I forgot to highlight is that the CPU will probably use specific registers for the calculations, which might be a of a certain size no matter the variables type/size
• 09-23-2008
jayee_spicyguy
Thanks alot you seems to be an encyclopedia to me. What I have to do if I want be like you my master.
• 09-23-2008
jayee_spicyguy
Thanks alot
• 09-23-2008
Elysia
From what I understand, all integers are considered as int, possible larger data types if the number does not fit inside an int.
However, the compiler must not choose a data type that can hold the result of the calculation if the calculation can not be done in compile time.
Calculations are done with both sides being the same size and the result also being of the same type that the types of the calculation is done with (ie if you are using int, the result is int, and if you use long, the result is long).
If the calculation does not fit inside the type of the result, you get overflow. To fix that, you must make sure at least one operand is of a bigger type to force the result to use a bigger type.

Correct me if I'm wrong somewhere here. I don't know if this is the same in C++ and C.