开发者

C - Need to shift an unsigned int right one place at a time.

I need to shift an unsigned int to the right more than 32 times and still get a proper answer of zero instead of the random or original number. E.g 8 >> 40 should = 0 but it returns a random number.

I understand a loop that shifts one place right at a time would solve this problem as it would fill in zeros as it went. However my current code for this doesn't work for some reason. What am I doing wrong?

unsigned int shiftR(unsigned int a, unsigned int b) {
  unsigned int i=0;
  while (i < b) {
      a >> 1;
      i++;
  }
  return a;
} 

This gives me a compile warning that it has no effect ( a >> 1;). How开发者_StackOverflow社区 come?

Thanks!


You want to use a >>= 1; or a = a >> 1; this is because a >> 1 shifts a to the right once and returns the result. It doesn't assign the result to a


I need to shift an unsigned int to the right more than 32 times and still get a proper answer of zero instead of the random or original number.

... Then do that?

unsigned int shiftR(unsigned int a, unsigned int b) {
  return (b >= 32) ? 0 : a >> b;
}

Why complicate things?


As far as I remember C, you need to say a = a >> 1.


As others noted, you never re-assigned a a new value; the result of that statement was not used for anything, so the compiler strips it out. a>>=1 is what you wanted.

I'd like to add though that if you want your unsigned int to be 32-bit, then force it. Use the C99 stdint.h library and make it uint32_t - nice and unambiguous.


a loop that shifts one place right at a time

You must change a >> 1; to a >>= 1;.

E.g 8 >> 40 should = 0 but it returns a random number.

In C, it is undefined behavior to left or right shift an integer by more places than the bit width of the integer type[0]. Stepping on undefined behavior is very bad, because nothing could happen, something bad could happen immediately, something bad could happen at an unknown point in the future, or something bad could happen on a different platform or compiler.

The correct way to deal with this is to manually check if you're shifting by more than 32 places, and then manually give a result of 0.

[0]: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html . You should read the whole page, but the specific section is "Oversized Shift Amounts".


a + 1 adds 1 with a but does not store anything anywhere, therefore the value of a is unmodified. To update the value of a with the incremented value you have to do a = a + 1 or a += 1 . similarly to shift the integer value in a by 1 and then store the shifted value in a you need to do a = a >> 1 or a >>= 1.

Because only doing a >> 1 does not modify the value of a, the compiler appropriately warns you that this statement has no effect, that means that keeping this statement or removing it does not matter, as it does not modify anything.

In your case you are shifting the value of a , b nos of times so you can simply use a >>= b instead of iterating a loop.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜