On Fri, 8 Jan 2016 09:58:36 -0800 (PST), Paul <
peps...@gmail.com>
wrote:
>The code below the asterisks is from a book. Since I don't want to either plug the book or criticise the book,
>I'd like to leave the precise reference unstated. The code is supposed to count the number of bits
>set to 1 in a 32 bits unsigned int. The technique is to calculate the answer for a single byte, memoize
>the answer, and then apply the answer for all four bytes.
>
>My questions are as follows:
>1) The u at the end of 0xffu seems redundant. It just means the bit pattern 11111111.
>If there were 16 fs instead of 2fs, then it would be relevant, however. Am I correct that the u is redundant?
I didn't try to determine if it makes a difference to the book's code
but the constant 0xff has type (signed) int and 0xffu has type
unsigned int. Since this constant is only used in conjunction with
the unsigned parameter n, having it unsigned eliminates the need to
perform any of the "usual arithmetic conversions" that occur when
signed and unsigned appear in the same expression.
>2) Does the word "static" in this context mean that bitInChar shouldn't change its value
>between function calls? What do we gain from the "static" concept here? If we
Since bitInChar is defined at file scope, its value is not dependent
on function calls. It only changes value when assigned to. What the
static qualifier does is give the name internal linkage which prevents
it from being accessed by name from a different translation unit.
>omit "static" but leave bitInChar global, then we can demonstrate the use of the bit-count function by:
>
>int main()
>{
> fillBitsInChar();
> const int i = 3287665;
> const int j = 679346;
> std::cout << std::endl << countBitsConstantFor32BitsInt(i) << std::endl
> << countBitsConstantFor32BitsInt(j) << std::endl;
>}
>
>3) How about the following idea of mine below? We don't want to waste time with fillBitsInChar() multiple
>times. So maybe we can have a static bool to make sure it's only done once. Is this code immediately below ok?
It is completely unnecessary. The expectation is your code would call
fillBitsInChar exactly once before you ever called
countBitsConstantFor32BitsInt, which you could then call as often as
you wanted. (Similar to calling srand exactly once before calling
rand as often as needed.)
>unsigned int myCountBits( unsigned int n)
>{
>
> static bool uninitialised = true;
> if(uninitialised)
> fillBitsInChar();
>
>uninitialised = false;
>
> return countBitsConstantFor32BitsInt(n);
>}
>
>I think I've answered my own question because my idea doesn't work if bitChar is
>not static. Have I correctly understood why "static" is used by the author?
Did you mean bitInChar? In what way does it not work? Without the
specifier static, bitInChar has external linkage and therefore static
duration. This means its lifetime is the entire execution of the
program and it retains its last_stored value throughout that lifetime.
The only effect the specifier has is to change the linkage from
external to internal.
>Many thanks for your help.
>
>Paul
>
>
>*****************************************************************
>BEGINNING OF CODE FROM BOOK.
>
>unsigned int countBits( unsigned int n)
>{
>unsigned int count = 0;
>while (n)
>{ count += n & 1;
>n >>= 1;
>}
>return count;
>}
>
>
>static int bitInChar[256];
>void fillBitsInChar()
> {
> for (unsigned int i = 0; i < 256; ++i)
> bitInChar[i] = countBits(i);
> }
>
> unsigned int countBitsConstantFor32BitsInt( unsigned int n)
> {
> return bitInChar[ n & 0xffu] + bitInChar[( n >> 8) & 0xffu]
> + bitInChar[( n >> 16) & 0xffu] + bitInChar[( n >> 24) & 0xffu];
> }
>
>END OF CODE FROM BOOK.
--
Remove del for email