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*/
Printable View
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*/
How in the world can you get 22464 in the first place? Mathematically, the result should be 88000.Quote:
if i gave y = 8000 and z = 1100 iam getting x as -1 instead of 22464
Oh wait, you are expecting an overflow, and sizeof(int) is 2 on your machine?
EDIT:
Right, here's the relevant text from C99:
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.Quote:
Originally Posted by C99 section 6.3.1.3
Here is what I tried in a 32bit CPU:
Compiled with: gcc -std=gnu99 and without -std=gnu99 and got: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("%d", x);
return 0;
}
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
Thanks alot you seems to be an encyclopedia to me. What I have to do if I want be like you my master.
Thanks alot
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.