Bitwise operations (shifting return values) - c

if (((number >> i) & 1) == 1)
this is my code example.
How is the return value determined in this operation? We shift numbers to the right or left. what is the return value?
if (((number >> i) & 1) == 1)

number >> i bitwise-shifts number to the right by i bits:
number i number >> i
------ - -----------
01010101 1 00101010
01010101 2 00010101
01010101 3 00001010
etc.
(number >> i) & 1 does a bitwise-AND of number >> 1 against 1:
00101010 (01010101 >> 1)
& 00000001
----------
00000000
00010101 (01010101 >> 2)
& 00000001
----------
00000001
So basically,
if (((number >> i) & 1) == 1)
will branch if the low bit of the shifted value is set.

How is the return value determined in this operation?
There is no return value. There is an if statement with the equality operator
if (((number >> i) & 1) == 1)
The result of the equality operator is value 0 or 1 of the type int dependent on whether two operands, ((number >> i) & 1) and 1, of the expression are unequal or equal to each other correspondingly. If the result is 1 (operands are equal each other) then the sub-statement of the if statement will get the control.
So the of statements checks whether the i-th bit of number is set to 1 or to 0.

>> is a right-shift operator in C language.
It depends on three factors that the result of ((number >> i) & 1) would be.
The type of the number is either signed or unsigned.
The total size in bit of the number, i.e. 8*sizeof(number).
The value of i.
number is signed
number is unsigned
The value of i >= The total size in bit of the number
the signed bit of number
0
The value of i < The total size in bit of the number
the i-th bit of number (LSb is 0-th bit)
the i-th bit of number (LSb is 0-th bit)

Related

Calculate the average bits of byte in C

I try to writ a function that calculate the average bits of byte.
float AvgOnesOnBinaryString (int x)
for example:
-252 is 11111111 11111111 11111111 00000100
so the function return 6.25
because ( 8+8+8+1) / 4 = 6.25
I have to use the function that count bits in char:
int countOnesOnBinaryString (char x){
int bitCount = 0;
while(x > 0)
{
if ( x & 1 == 1 )
bitCount++;
x = x>>1;
}
return bitCount;
}
I tried:
float AvgOnesOnBinaryString (int x){
float total = 0;
total += countOnesOnBinaryString((x >> 24));
total += countOnesOnBinaryString((x >> 16));
total += countOnesOnBinaryString((x >> 8));
total += countOnesOnBinaryString(x);
return total/4;
}
but I get the answae 0.25 and not 6.25
what could be the problem?
UPDATE
I can't change the AvgOnesOnBinaryString function signature.
The C language allows compilers to define char as either a signed or unsigned type. I suspect it is signed on your platform, meaning that a byte like 0xff is likely interpreted as -1. This means that the x > 0 test in countOnesOnBinaryString yields false, so countOnesOnBinaryString(0xff) would return 0 instead of the correct value 8.
You should change countOnesOnBinaryString to take an argument of type unsigned char instead of char.
For somewhat related reasons, it would also be a good idea to change the argument of AvgOnesOnBinaryString to be unsigned int. Or even better, uint32_t from <stdint.h>, since your code assumes the input value is 32 bits, and (unsigned) int is allowed to be of some other size.
There is one algorithm that gives you the count of the number of 1 bits in an unsigned variable far more quickly. Only 5 iterations are needed in a 32 bit integer. I'll show it to you in C for a full length 64 bit unsigned number, so probably you can guess the pattern and why it works (it is explained below):
uint64_t
no_of_1_bits(uint64_t the_value)
{
the_value = ((the_value & 0xaaaaaaaaaaaaaaaa) >> 1) + (the_value & 0x5555555555555555);
the_value = ((the_value & 0xcccccccccccccccc) >> 2) + (the_value & 0x3333333333333333);
the_value = ((the_value & 0xf0f0f0f0f0f0f0f0) >> 4) + (the_value & 0x0f0f0f0f0f0f0f0f);
the_value = ((the_value & 0xff00ff00ff00ff00) >> 8) + (the_value & 0x00ff00ff00ff00ff);
the_value = ((the_value & 0xffff0000ffff0000) >> 16) + (the_value & 0x0000ffff0000ffff);
the_value = ((the_value & 0xffffffff00000000) >> 32) + (the_value & 0x00000000ffffffff);
return the_value;
}
The number of 1 bits will be in the 64bit value of the_value. If you divide the result by eight, you'll have the average of 1 bits per byte for an unsigned long (beware of making the shifts with signed chars as the sign bit is replicated, so your algorithm will never stop for a negative number)
For 8 bit bytes, the algorithm reduces to:
uint8_t
no_of_1_bits(uint8_t the_value)
{
the_value = ((the_value & 0xaa) >> 1) + (the_value & 0x55);
the_value = ((the_value & 0xcc) >> 2) + (the_value & 0x33);
the_value = ((the_value & 0xf0) >> 4) + (the_value & 0x0f);
return the_value;
}
and again, the number of 1 bits is in the variable the_value.
The idea of this algorithm is to produce in the first step the sum of each pair of bits in a two bit accumulator (we shift the left bit of a pair to the right to align it with the right one, then we add them together, and in parallel for each pair of bits). As the accumulators are two bits, it is impossible to overflow (so there's never a carry from a pair of bits to the next, and we use the full integer as a series of two bit registers to add the sum)
Then we sum each pair of bits in an accumulator of four bits and again, that never overflows... let's do the same thing with the nibbles we got, and sum them into registers of 8 bits.... If it was impossible to overflow a 4 bit accumulator with two bits, it is more impossible to overflow an 8 bit accumulator with four bit addings.... and continue until you add the left half of the word with the right half. You finally end with the sum of all bits in one full length register of the word length.
Easy, isn't it? :)

Trouble in understanding the bitwise operators left and right shift function in programming [duplicate]

This question already has answers here:
Need help understanding "getbits()" method in Chapter 2 of K&R C
(6 answers)
Closed 3 years ago.
In ANSI C section 2.9, the bitwise operators, I am unable to understand this particular code.
I know how each bitwise operator works, but combinations need some help.
getbits(x, 4, 3)
unsigned getbits(unsigned x, int p, int n) {
return (x >> (p + 1 - n)) & ~(~0 << n);
}
~0 is an int made of binary ones (111...111111)
~0<<n introduces n zeros in the lower bits (111...111000).
~(~0<<n) flips the bits (000...000111)
x>>(p+1-n) shifts x towards the lower bits (00XXX...XXXXXX).
The & operation combines the previous two results: upper zeros are kept as zeros and the lower X bits (facing the ones) are kept as is (00000...000XXX).
Thus this function retrieves a n-bit pattern of x from bit p, but shifted (p+1-n) positions towards lower bits (ie, placed at the lower position).
The function is supposed to extract a bitfield of width n at position p.
There are problems in this function:
p + 1 - n seems bogus but it is the number of bits to the right of the bitfield if p is the bit number of the most significant bit in the bitfield, numbered from 0 for the least significant bit..
the code has implementation defined behavior if the most significant bit of x is included in the bitfield because 0 is a signed integer. 0U should be used instead.
the code does not work to extract a bitfield that has the full width of unsigned int, because shifting by a number of bits greater or equal to the width of the type has undefined behavior. The shift should be split in 2 parts, n - 1 bits and an additional 1 bit. n - 1 will be in the range [0..31] so the variable shift is fully defined.
Here is a more portable version:
// extract `n` bits at position `p`. n in [1..32], p in `[1..32]`
unsigned getbits(unsigned x, int p, int n) {
return (x >> (p + 1 - n)) & ~(~0U << (n - 1) << 1);
}
Here are the steps:
0U is the unsigned int null constant.
~0U has all its value bits set.
~0 << (n - 1) has all its value bits set except for the n - 1 low order bits, which are cleared.
~0 << (n - 1) << 1 has all its value bits set except for the n low order bits, which are cleared.
~(~0 << (n - 1) << 1) has the n low order bits set.
p + 1 - n is the number of bits with lower order than the bitfield
x >> (p + 1 - n) shifts the value to the right, leaving the bitfield in the low order bit positions.
(x >> (p + 1 - n)) & ~(~0 << (n - 1) << 1) masks the higher order bits, leaving just the bitfield value.
Note that there are other ways to compute the mask:
~0U >> (sizeof(unsigned) * CHAR_BIT - n)
(1U << (n - 1) << 1) - 1

How does this bits reversion in a byte work?

I'm new to programming and I found this method to reverse bits in a byte in C:
//(10000011) -> (11000001)
unsigned char reverse(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
posted by an user in answer to this question, but I can't understand how it works. What do these constants mean?
It might help to look at the binary representation of the above numbers:
0xF0: 11110000
0x0F: 00001111
0xCC: 11001100
0x33: 00110011
0xAA: 10101010
0x55: 01010101
The first pair of numbers are used to mask out and swap the first 4 bits and the last 4 bits of a byte.
The second pair masks out and swaps the first 2 bits and last 2 bits of a set of 4 bits.
The third pair masks out and swap adjacent pairs of bits.
The code first swaps the "nibbles", i.e. most significant 4 bits with least significant 4 bits. Then it swaps two top order pairs together, and bottom pairs together; finally it does pairwise swaps of 2n and 2n+1 bits.
I am going to denote the bits of the original value of b here by their exponent, in angle brackets (this is just a pseudo notation that I am using here, not correct C); I use o to mark any bit that is 0 always. So in the beginning we have
<76543210>
No in the first operation we have
<76543210> & 0xF0 -> <7654oooo>
<76543210> & 0x0F -> <oooo3210>
Now the former is shifted right by 4 bits, and the latter left by 4, thus we get
<7654oooo> >> 4 -> <oooo7654>
<oooo3210> << 4 -> <3210oooo>
Finally these are or'ed together, and thus after the statement
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
the value of b is the permutation <32107654> of the original bits.
In the second statement the mask 0xCC is 11001100 in binary, and 0x33 is 00110011 in binary; the intermediate values are:
(<32107654> & 0xCC) >> 2 -> <32oo76oo> >> 2 -> <oo32oo76>; and
(<32107654> & 0x33) << 2 -> <oo10oo54> << 2 -> <10oo54oo>.
These 2 or'ed together will result in permutation <10325476>. Now finally, the mask 0xAA is 10101010 in binary, and 0x55 is 01010101. Thus we have
(<10325476> & 0xAA) >> 1 -> <1o3o5o7o> >> 1 -> <o1o3o5o7>; and
(<10325476> & 0x55) << 1 -> <o0o2o4o6> << 1 -> <0o2o4o6o>
These or'ed together will result in permutation <01234567> which is the reverse of the original.
So it's just a lot of bit shifting. The bits are in the following order:
76543210
Now, first line, first part keeps high bits, sets lower bits to 0 (mask is 0b11110000), shifts them 4 to the right. Second part does the same for the lower bits (mask is 0b00001111), and shifts to the left:
first line, first part: 7654xxxx => xxxx7654 (bits shift to the right)
first line, second part: xxxx3210 => 3210xxxx (bits shift to the left)
add them together: => 32107654
Then, second line. Same action, different masks (0b11001100 and 0b00110011, respectively), with 32107654:
second line, first part: 32xx76xx => xx32xx76 (bits shift to the right)
second line, second part: xx10xx54 => 10xx54xx (bits shift to the left)
add them together: => 10325476
Third line is the same with a again other masks(0b10101010 and 0b01010101, respectively), with 10325476:
third line, first part: 1x3x5x7x => x1x3x5x7 (bits shift to the right)
third line, second part: x0x2x4x6 => 0x2x4x6x (bits shift to the left)
add them together: => 01234567
So we end up, finally, with the action:
76543210 => 01234567
Let's number the bits in b as follows:
01234567
0xF0 in binary is 11110000, and 0x0F is 00001111. The first assignment shifts the leftmost 4 bits to the right, and the rightmost 4 bits to the left, then combines them with OR, so the result is:
45670123
0xCC is 11001100, and 0x33 is 00110011. When these masked bits are shifted by 2 bits and combined, the result is:
67452301
Finally, 0xAA is 10101010 and 0x55 is 01010101. When these masks and shifts are done, the result is:
76543210
Voila! this is the reversed order.
Notice that for each pair of shifts, the bit masks are inverses of each other, and the number of bits being shifted are the same as the length of the sequences of 1 bits in the mask. So each of them is swapping groups of bits whose size is that sequence length.
You need to understand 4 main things in order to understand what above code means.
& (AND) Bitwise Operator.
| (OR) Bitwise Operator.
>> (Right Shift Operator).
<< (Left Shift Operator).
Luckily, I just have written a detailed blog that explains everything about Number System and Bit Manipulation

Right shift with bitwise AND

A solution from a top answer is
To check a bit, shift the number x to the right, then bitwise AND it:
bit = (number >> x) & 1;
That will put the value of bit x into the variable bit.
What confuses me is this, when assuming the following:
unsigned number = 5; //0101
int x = 2; //
After a shift (number >> x) we get 0001. But we shifted off bits 1 and 2 and so when we do the bitwise AND, aren't we doing it against the third bit and not the second, where x = 2? Doesn't this mean that if I want to check if bit x is set, shouldn't I do:
bit = (number >> (x - 1)) & 1);
Yes, you are doing the bitwise AND against the third bit. Consider x to be zero-indexed, i.e. the first bit is bit 0.
You said:
After a shift (number >> x) we get 0001. But we shifted off bits 1 and 2 and so when we do the bitwise AND, aren't we doing it against the third bit and not the second, where x = 2? Doesn't this mean that if I want to check if bit x is set, shouldn't I do:
bit = (number >> (x - 1)) & 1);
To get the value of the 1st least significant bit, you need (number >> 0) & 1.
To get the value of the 2nd least significant bit, you need (number >> 1) & 1.
To get the value of the 3rd least significant bit, you need (number >> 2) & 1.
etc.
In other words,
1st implies 0 bits to shift
2nd implies 1 bits to shift
3rd implies 2 bits to shift
Nth implies N-1 bits to shift
I hope that makes it a little bit clearer for you.
The bit number represents the power of two. Thus when x is two, you are talking about bit 2 = 2**2 = 4.
The least-significant bit (or 'right most' bit if you prefer it bit 0, not bit 1.
Also, there is no reason to actually do the bit shift unless your 'bit number' is in a variable.
For example, to test bit 5 of a value, simply do
if (variable & 0x20)
bit_is_set();
Here 0x20 is simply 2**5, (or 1 << 5)

how do I set up an if statement

How would I go about setting up an if statement using only the following bitwise operations:
!
~
&
^
|
&plus;
<<
>>
As an example: "if x is negative then add 15"
This would mean that if the input was x = 0xF0000000, then we would produce 0xF000000F. If the input was x = 0x00000004, we would produce 0x00000004.
You can add 15 to a number if it is negative, and 0 otherwise as follows. Shifting a negative number right will shift in 1's if the value is negative, and 0's otherwise. Shifting by 31 will fill the int with either 1's or 0's. ANDing by 0xF will set the summand to 15 if it is negative, and 0 otherwise, resulting in no change to x.
x += (x >> 31) & 0xF;
If you're worried about the implementation dependent behavior of shifting a signed number to the right. You can do the same thing with the following code, however you still are depending on a two's complement representation of the number. The shift results in 0 or 1, the multiplication scales the number to the appropriate value.
x += (((unsigned)x >> 31) * 0xF);

Resources