开发者

Strange problem about a function that gets the machine word

I wrote a function to get the mach开发者_开发技巧ine word in C yesterday, but it seems that there is something wrong in it.

Here is the code:

unsigned machineword()
{
int i = 1;
unsigned temp;
while (temp > 0)
{
    i++;
    temp = (unsigned)(~0 >> i);
}
return i;
}


The simplest way to get the width of unsigned int is (sizeof(unsigned)*CHAR_BIT).

EDIT: as noted by pmg, you should be aware of the theoretical difference between the size an unsigned takes in memory and the number of bits available for computing with. Your original code tries to compute the latter, and so does the program below. The above trick computes the space occupied in memory.

It is not very convenient to compute this number with >> as it is forbidden in C to use >> with a number equal to or larger than the size in bits of the type you are shifting. You can work around this, if you know that long long is strictly larger than int, by computing with unsigned long long:

unsigned machineword()
{
  int i = 1;
  unsigned temp=1;
  while (temp > 0)
  {
    i++;
    temp = (unsigned)(((unsigned long long)~(0U)) >> i);
  }
  return i;
}


The simplest way to avoid the UB when shifting for too large value while keeping your structure is:

unsigned machineword()
{
   unsigned i = 0;
   unsigned temp = ~0U;
   while (temp > 0)
   {
      i++;
      temp >>= 1;
   }
   return i;
}


To calculate the number of bits, you can use CHAR_BIT or UINT_MAX.
The CHAR_BIT approach gives you the number of bits each value occupies in memory.
The UINT_MAX approach gives you the effective available bits.

Usually both values will be the same

#include <limits.h>
#include <stdio.h>

int main(void) {
  unsigned tmp = UINT_MAX;
  int i = 0;
  while (tmp) {
      i++;
      tmp /= 2;
  }
  printf("value bits in a unsigned: %d\n", i);
  printf("memory bits in a unsigned: %d\n", CHAR_BIT * (int)sizeof (unsigned));
  return 0;
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜