简体   繁体   中英

Can't understand what this C program is doing?

When I was preparing for some interview I got the following

count=0;
for(i=1;i<=n;i++)
{
    i=(i)&(i-1);    //line 4
    count++;
}
return count;
//--------

i=21,22 same count. For what other values of i we get same count?

I was not able to understand what line 4 is doing. Can anyone please help me and give me the output of the program.....

Found the above question(9) in the link http://placement.freshersworld.com/placement-papers/Mentor-Graphics/Placement-Paper-Aptitude-General-32412

i & (i-1) returns 0 if i is a power of 2 or if i is 0, non zero otherwise.

On inspection, i will be set to zero, count incremented, then i will become 1 again, then 0, and so on.

I'm not sure that this loop will terminate .

Warning
After looking over your code a second time, I must say, it may compile just fine, but you are going to encounter a deadlock, I do think:

for (i=1;i<=n;++i)
{
    i = (i)&(i-1);
    cont++;
}

What will happen? When i is 1 :

i = 1&0;//is what line 4 boils down to

So i will be 0 , if the loop started, then n will be at least 1, so the loop condition still is true:

i<=n => 0 <= n ==> true

So i is incremented by 1 ( i++ ), and the whole thing starts again. Line four, once again, evaluates to:

i = 1&0;//assigns 0 again to i

And you're back to square one. This program will never terminate, it'll simply repeat the same operation over and over and over...


Well, & is the bitwise AND operator. It When used, as in your snippet with 2 integers, it returns the bits that are "switched on" or set to 1 in both numbers. In plain English: the expression evaluates to a new set of bits, which were set in both operands. Take, for example, when i is 2:

00000010 //2
00000001 // i - 1
--------
00000000

In this case, non of the bits are set to 1 in both cases. As indeed this will be the fact for all powers of two, because the powers of 2 look like this in binary:

00000010
00000100
00001000

And a power of 2 minus 1 looks like this:

00001000//power of 2
00000111

In all other cases, there will, at least be 1 bit that is set to 1 in both cases:

00000110
00000101
--------
00000100

Easy.


For a more complete overview, and detailed explanation of bitwise operators in C, you can always refer to the wiki on bitwise operators in C

The line

i = i & (i-1)

clears the lowest set bit of i . So a loop like

while (i) {
    i = i & (i-1);
    count++; }

counts the number of set bits in i . Note that this really only works if i has an unsigned type. If i is signed and negative, it causes undefined behavior.

The link you give is probably a misremembered question (left off the while (i) ) asking about a loop like this.

The comment "i=21,22 same count" is a hint that 21(10101) and 22(10110) have the same number of set bits.

I must admit that when I read your question the first time, I actually saw the while(i) loop as the lines i=(i)&(i-1); count++; i=(i)&(i-1); count++; really only make sense in that context, and its such a common "trick question" idiom.

& is a bit-wise AND operator.It computes as follows:

for eg: i=8

i & (i-1)  is (1000) AND (0111) results 0000.

if you run the program it gets into infinite loop since

i=1 and (i) & (i-1) gives 0 

every time i becomes 1

so, modify the code as follows and I hope you will get the answer:

for(i=1;i<=n;i++)
{
    count=(i)&(i-1);
    printf(" i= %d  count= %d",i,count);
}

The result is as follows:

i= 1 count= 0
i= 2  count= 0
i= 3  count= 2
i= 4  count= 0
i= 5  count= 4
i= 6  count= 4
i= 7  count= 6
i= 8  count= 0
i= 9  count= 8
i= 10  count= 8
i= 11  count= 10
i= 12  count= 8
i= 13  count= 12
i= 14  count= 12
i= 15  count= 14
i= 16  count= 0
i= 17  count= 16
i= 18  count= 16
i= 19  count= 18
i= 20  count= 16
i= 21  count= 20
i= 22  count= 20
i= 23  count= 22
i= 24  count= 16
i= 25  count= 24

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM