Reputation: 51
I have tried following program in C language and the result of the program is:
Output : 0 is printed at last when the i
is unsigned int
, when the value of i
is 0, then the control should not go inside the while loop since I have given i>0
condition, but 0 is printed, I didn't understand how it is possible.
When the i
is signed int
, then 0 is not printed.
Please let me know what is happening in the program.
#include <stdio.h>
#include <string.h>
main()
{
unsigned int i=1;
int c=1;
while(i>0)
{
i=i*2;
c++;
printf("%d\n",i);
}
printf("%d c value is",c) ;
}
Upvotes: 1
Views: 207
Reputation: 95
In case of unsigned int:
supposing int
takes 4 bytes, the value of i becomes "1073741824"
for which the binary notation is
"01000000 00000000 00000000 00000000"
Multiplying it by two again makes the decimal value "2147483648"
which the binary notation is
"10000000 00000000 00000000 00000000".
Again multiplying it by two makes the binary notation as follows
"00000001 00000000 00000000 00000000 00000000".
But as int
occupies only four bytes, 4 least significant bytes are all filled zero, so the value of i becomes zero.
In case of signed int:
Most significant bit is used for indication of negative or positive values. 1 for negative numbers. so it prints negative number further multiplying i by 2. Which makes the while condition fails. as negative number is not greater than zero.
Upvotes: 2
Reputation: 6116
You have printed i
inside while
after computing i = i*2;
hence when i
is unsigned
and has value 2^31
, the while
condition is true
and it is again multiplied by 2
, where it becomes 0
due to integer overflow, which is printed and loop gets over the next time while(i > 0)
condition is checked.
For signed int
, the behavior is undefined as pointed out by @Anonymous.
However here it seems that (you cannot rely on this behavior!!) condition of while
fails when i
equals 2^31
because it is treated as negative number now (sign bit is 1
), hence it is not multiplied by 2
and doesn't become 0
.
If you do not want to see 0
output, you can try doing printf
before i = i*2
statement.
Upvotes: 2
Reputation: 206577
Change the while
loop so that printf
is called first. Also, use %u
for unsigned int
instead of %d
.
while(i>0)
{
printf("%u\n",i);
i=i*2;
c++;
}
With this change you will be printing only the value of i
that pass the conditional of the while
statement.
Upvotes: 1
Reputation: 141574
Using %d
with unsigned int
causes undefined behaviour. To fix your program, change %d
to %u
and then the results will make more sense.
When i
gets to 231 (assuming you have 32-bit ints) and you do i * 2
then the result , which would be 232 actually wraps around to 0
, which is why your loop ends. Unsigned integers wrap around like this (technical definition is arithmetic modulo UINT_MAX+1
).
If i
is signed int (and you use %d
) then you cause undefined behaviour when i * 2
would exceed INT_MAX
, so anything can happen.
Upvotes: 5