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;
}
精彩评论