How to return middle bits? - c

I searched online and the common solution for returning x bits from start seems to be:
mask = ((1 << x) - 1 ) << start
then, mask & value.
However, I'm confused on how this works still.
If I have a number 0101 1100 and I want to return the two bits from positions 5 and 6 (11)
mask = ((1<<2)-1) << 5
1<<2 = 0000 0100, and subtracting 1 yields 0000 0011 then, shifting 5 is 0110 0000
If I take 0110 0000 & 0101 1100 (the original), I get 0100 0000
This is not the answer I want, so what am I doing wrong?

Assuming we're referring to two's complement binary, then 11 would be bits 2 and 3 (or 3 and 4, depending on who you ask).
Think of it this way. If you want to get a specific amount of bits from the middle of a binary value, then you can first shift it to the right n times where n is the index of the first bit of interest.
Shifting 0101 1100 to the right twice yields 0001 0111
Here, we're interested in the first two bits, so we can simply call 0001 0111 & 3 because 3 = 00000011.
Therefore, the formula for this specific example is (b >> 2) & 3 where b is the binary value.
If you want the value at their current location, you can call 0101 1100 & 12 because 12 = 00001100, which returns 0000 1100.

Bit positions are typically counted from least- to most-significant, i.e. right-to-left.
0101 1110
---- ----
7654 3210
The bits you want are bits 2 and 3.

for e.g input num is 92 = 0101 1100
initial pos = 1
ending pos = 4
Now your task is to find the number b/w 1st and 4th position(LSB to MSB), output should be 11 means 3.
First find the no of ones b/w these 2 positions, for this rotate loop from starting position to ending position and do
sum = sum | 1<<i; // sum =12( 1100)
Next if you do sum & num, you will get output b/w given positions which is 1100 but you need 11 so do 1100 >> 2(which is n1+1)
Here is the my solution
int sum = 0,num,res; /** num is your input number **/
for(int i=n1+1;i<n2;i++) /* n1 is starting position and n2 is the ending position */
sum = sum | (1<<i); //counting ones
res = sum & num; // we will get o/p in middle
res = res>>(n1+1); // shift previous res to correct position
Finally prints the res.

As advised by many, you should start your positioning from the right.
num = 0101 1100
Positions: 8765 4321
Then the given solution work's just fine.
However, a more detailed approach by myself would be:
To get the values of the bits at position 3 and 4 ('11'), I would do the following:
Let's say you want the bit at position k. Shift a 1, k-1 positions to the left and evaluate it with the &-operator. Shift it back, then save the result in an array with the length of how many bits you want. Repeat the process for the rest.
int mask = 1 << (k - 1);
int bitAtPosK = (num & mask) >> (k - 1);
... do this in a loop and save the results.
Visualisation for Position 3:
num = 0101 1100
1 << 2 results in 0000 0010
and
0101 1100
0000 0100
--------- &
0000 0100
0000 0100 >> 2 results in 1

Related

A question to C operations :return 1 when all bits of byte i of x equal 1; 0 otherwise

You are asked to complete the following C function:
/* Return 1 when all bits of byte i of x equal 1; 0 otherwise. */
int allBits_ofByte_i(unsigned x, int i) {
return _____________________ ;
}
My solution: !!(x&(0xFF << (i<<3)))
The correct answer to this question is:
!~(~0xFF | (x >> (i << 3 ))
Can someone explain it?
Also, can someone take a look at my answer, is it right?
The expression !~(~0xFF | (x >> (i << 3 )) is evaluated as follows.
i<<3 multiplies i by 8 to get a number of bits which will be 0, 8, 16, or 24, depending on which byte the caller wants to test. This is actually the number of bits to ignore, as it is the number of bits that are less significant than the byte we're interested it.
(x >> ...) shifts the test value right to eliminate the low bits that we're not interested in. The 8 bits of interest are now the lowest 8 bits in the unsigned value we're evaluating. Note that other higher bits may or may not be set.
(~0xFF | ...) sets all 24 bits above the 8 we're interested in, but does not alter those 8 bits. (~0xFF is a shorthand for 0xFFFFFF00, and yes, arguably 0xFFu should be used).
~(...) flips all bits. This will result in a value of zero if every bit was set, and a non-zero value in every other case.
!(...) logically negates the result. This will result in a value of 1 only if every bit was set during step 3. In other words, every bit in the 8 bits we were interested in was set. (The other 24 bits were set in step 3.)
The algorithm can be summed up as, set the 24 bits we're not interested in, then verify that 32 bits are set.
Your answer took a slightly different approach, which was to shift the 0xFF mask left rather than shift the test value right. That was my first thought for how to approach the problem too! But your logical negation doesn't verify that every bit is set, which is why your answer wouldn't produce correct results in all cases.
x is of unsigned integer type. Let's say that x is (often) 32 bit.
One byte consists of 8 bits. So x has 4 bytes in this case: 0, 1, 2 or 3
According to the solution the endianness of the architecture can be imagined as follows:
x => bbbb bbbb bbbb bbbb bbbb bbbb bbbb bbbb
i => 3 2 1 0
I will try to break it down:
!~ ( ~0xFF | ( x >> (i << 3) ) )
i can be either 0, 1, 2 or 3. So i << 3 would either give you 0, 8, 16 or 24. (i << n is like multiplying by 2^n; it means shift i to the left n times putting 0).
Note that 0, 8, 16 and 24 are the byte segments: 0-7, 8-15, 16-23, 24-31
This is used to ...
x >> (i<<3) shifts to the right x by that result (0, 8, 16 or 24 times). So that the corresponding byte denoted by the i parameter occupies now the right most bits.
Until now you manipulated x so that the byte you are interested in is located on the right most 8 bits (the right most byte).
~0xFF is the inversion of 0000 0000 0000 0000 0000 0000 1111 1111 which gives you 1111 1111 1111 1111 1111 1111 0000 0000
The bitwise or operator is applied to the two results above, which would result in
1111 1111 1111 1111 1111 1111 abcd efgh - the letters being the bits of the corresponding byte of x.
~1111 1111 1111 1111 1111 1111 abcd efgh will turn into 0000 0000 0000 0000 0000 0000 ABCD EFGH - the capital letters being the inverse of the lower letters' values.
!0000 0000 0000 0000 0000 0000 ABCD EFGH is a logical operation. !n is 1 if n is 0, and it is 0 if n is otherwise.
So you get a 1 if all the inverted bits of the corresponding byte were 0000 0000 (i.e. the byte is 1111 1111).
Otherwise you get a 0.
In the C programming language a result of 0 corresponds to a boolean false value. And a result different than 0 corresponds to a boolean true value.

generating numbers using a n-bit number (similar to generating subsets of n-bit value)

Given a number 'n' and the corresponding binary value. I want to generate all combinations of n, using only the bits set in 'n'.
for example: if n=11 and its binary representation 1011, the combinations are:
0000
0001
0010
0011
1000
1001
1010
1011
example 2: if n=49 and its binary representation is 11001, the combinations are:
00000
00001
01000
01001
10000
10001
11000
11001
The easiest way could be to write a C subroutine to generate these combinations, however, i need some efficient way/algorithm for generating these combinations (some bit manipulation techniques similar to bit twiddling hacks).
Thanks.
Here's an illustration of a technique using simple bit twiddling. It uses the guaranteed semantics of binary arithmetic on unsigned values.
In the expression i = n & (i - n) below, all the sub-expressions, i, n, (i - n) and n & (i - n) are the same type, unsigned int and are unaffected by the integer promotion rules. Mathematically, the sub-expression (i - n) is evaluated modulo 2m, where 2m - 1 is the maximum value that can be represented by an unsigned int.
#include <stdio.h>
int main(void)
{
unsigned int n = 49;
unsigned int i;
for (i = 0; ; i = n & (i - n)) {
printf("%u", i);
if (i == n)
break;
putchar(' ');
}
putchar('\n');
return 0;
}
Example step
Assuming n is 49, or 0000000000110001₂, and the current value of i is 16, or 0000000000010000₂. Then for 16-bit, 2's complement arithmetic, we have:
0000000000010000₂
0000000000110001₂ -
----------------
1111111111011111₂
0000000000110001₂ &
----------------
0000000000010001₂ (= 17)
This is vaguely similar to the well-known technique to find the lowest '1' bit in an unsigned value x as x & -x, which works because ANDing a number with its two's complement leaves only the lowest '1' bit set in the result.
Get the binary string for your number.
Create a tree node labeled Z.
Let node := Z.
Let N := 1.
Read symbol N of your string (from the left, 1-indexed)
If symbol is 1, add two children of node; label the first child with node's label + 1, the other with node's label + 0. If symbol is 0, add one child of node; label the child with node's label + 0.
Increment the value of N.
Repeat steps 5 - 7 for all children of node, recursively, until in step 7 you increment the value of N to a value larger than the length of your original binary string. That condition terminates the recursion.
Once the tree has been so constructed, the leaves of the tree are labeled with your allowed values. Any tree traversal mechanism which visits the leaves will allow you to recover the allowed binary strings.
Iterating integers through only certain allowed bits? How about this function:
int NextMasked (int val, int mask) {
return ((val | ~mask) + 1) & mask;
}
Function step by step:
take previous value val and set all the bits to 1, which are NOT set in the mask
increment resulting value by 1
now; clear all bits what we set earlier, only allowing same bits what are set in the mask
tada.wav; we have new value and we going to return it to caller.
Let's test this with your example (mask = 11 and initially val = 0):
Here all values are in binary:
val = 0000, mask = 1011, ~mask = 0100 (bits inverted)
(old) (new)
val |~mask +1 &mask
0000 0100 0101 0001
0001 0101 0110 0010
0010 0110 0111 0011
0011 0111 1000 1000
1000 1100 1101 1001
1001 1101 1110 1010
1010 1110 1111 1011
1011 1111 10000 00000 <-- zeroed, you know it ended
Because this was so fun, let's test your another example (mask = 49):
Here all values are in binary:
val = 00000, mask = 11001, ~mask = 00110 (bits inverted)
(old) (new)
val |~mask +1 &mask
00000 00110 00111 00001
00001 00111 01000 01000
01000 01110 01111 01001
01001 01111 10000 10000
10000 10110 10111 10001
10001 10111 11000 11000
11000 11110 11111 11001
11001 11111 100000 000000 <-- again, wrapped around (zeroed)
It's late and I did not actually tested on the computer. But this should work, or give the idea...

what does bit_test() function do?

I'm reading Programming in C, 4th edn by Stephen Kochan.
Exercise: Write a function called bit_test() that takes two arguments: an unsigned int and a bit number n. Have the function return 1 if bit number n is on inside the word, and 0 if it is off. Assume that bit number 0 references the leftmost bit inside the integer. Also write a corresponding function called bit_set() that takes two arguments: an unsigned int and a bit number n. Have the function return the result of turning bit n on inside the integer.
This is one of the exercise's answers on their forum.
12-5
-----
/* test bit n in word to see if it is on
assumes words are 32 bits long */
int bit_test (unsigned int word, int n)
{
if ( n < 0 || n > 31 )
return 0;
if ( (word >> (31 - n)) & 0x1 )
return 1;
else
return 0;
}
unsigned int bit_set (unsigned int word, int n)
{
if ( n < 0 || n > 31 )
return 0;
return word | (1 << (31 - n));
}
Now I tried to understand it like this and as per my understanding it always returns 0. What does this function actually do?
It just checks whether a bit is set or not.
It assumes that it unsigned int is stored in 32 bit on that particular system.
Why the check?
Check is needed to make it safe ( I am not shifting a negative value or value greater than 31 ) As first one complains of being an error and the seecond one is useless as it returns 0.
what it really does in (word >> (31 - n)) & 0x1 )?
x x y x x x x x x
0 1 2 3 4 5 6 7 8
|-----------|
8-2=6
(Here I considered 9 bit words instead of 32. In your case it will be 31-3=28
So right shift it 6 bit
0 0 0 0 0 0 x x y
Now how to check if it is set or not?
0 0 0 0 0 0 x x y
& 0 0 0 0 0 0 0 0 1
________________________
0 0 0 0 0 0 0 0 y if it is set it returns 1 else 0
if that bit is et the result will be 1 else 0.
What does bit_set do?
It returns that nth bit set.
So if you input
0001 0010 1
and set bit is 0 (you want to set bit at position 0) then you will get
1001 0010 1
return word | (1 << (31 - n));
let the word be 0001 1001 1
You want to set bit 2 [0 indexing]
0001 1001 1
| 0010 0000 0
0011 1001 1
You have to apply logical or operation on with that value.
How to get that value?
Here we just want this number
0010 0000 0
|-------|
6 shift needed (left shift)
1 << (8-2) ---> is how you get it.
Or in your case 1<<(31-n)
Now I get what you are thinking wrong.....
You considered 25
0000 0000 0000 0000 0000 0000 0000 1101
The bit in 3rd (0 indexing) position is this
000[0] 0000 0000 0000 0000 0000 0000 1101
This bit is unset or 0.
Try 29th position of number 25 you will get 1 as answer.
The problem statement has us identify the leftmost, or highest order bit as n = 0, and the rightmost, or lowest order bit as n = 31.
The bit_test() function shifts the test bit to the lowest order position and does a bitwise AND to find if the test bit was set. For example, to test if the bit n = 0 is set for the bit pattern:
1111 1111 1111 1111 1111 1111 1111 1111
there is a shift to the right (word >> 31 - 0):
0000 0000 0000 0000 0000 0000 0000 0001
then the bitwise AND with 0x1 evaluates to 1, indicating that the n = 0 bit was set.
The bit_set() function shifts a bit-pattern with only the lowest order bit set to the left so that only the bit indicated by n is set, and then combines this bit pattern with the input number using a bitwise OR to set the n bit. If the input number is 0, and n = 3, then the lowest order bit of the bit pattern for 1 (or 0x1):
0000 0000 0000 0000 0000 0000 0000 0001
is shifted to the left (1 << 31 - 3):
0001 0000 0000 0000 0000 0000 0000 0000
and combined with the bit-pattern for 0 using a bitwise OR:
0001 0000 0000 0000 0000 0000 0000 0000
The result is that the n bit of the input number is set to 1.

Understanding a program in C

# include <stdio.h>
int main()
{
int n, c, k;
printf("Enter an integer in decimal number system\n");
scanf("%d", &n);
printf("%d in binary number system is:\n", n);
for (c = 31; c >= 0; c--)
{
k = n >> c;
if (k & 1)
printf("1");
else
printf ("0");
}
printf("\n");
return 0;
}
Can someone help me understand how does this code work? I found this in an online site. It gives the binary counterpart of the number when the decimal is entered. But I don't understand how it is working. And also what does the symbol n>>c mean? Sorry if this is too silly, I am just a beginner in C. Please help me if you can. Thanks a lot.
Okay:
We declare some integers for use later in the program.
int n, c, k;
We get an input number from the user. printf() will print the string to the screen, and scanf() will request data from the user and store it in n.
printf("Enter an integer in decimal number system\n");
scanf("%d", &n);
We now print back to the user the value of n
printf("%d in binary number system is:\n", n);
This is a for loop. It has three parts. The first part gets run before we enter the loop, but only on the first iteration of the loop. So we set c to 31. Then, we check the condition. Is c >= 0? Yes. It is.
We can ignore the last part for now.
for (c = 31; c >= 0; c--)
{
This assigns to k the value of n shifted to the right c times. This is similar to dividing a number by 2 and then removing any decimals. So 5 >> 2 == 1. And 7 >> 1 == 3. Many calculator programs have this button as well.
This iteration, we have n as whatever the user input (Let's say 52). and c is 31. So this would have a value of 0 this loop.
k = n >> c;
Now, this test functions as an even or odd test. If it is odd, we print 1, and 0 otherwise. This also can be seen as looking at the bottom bit of a number and choosing if it is 1 or 0.
if (k & 1)
printf("1");
else
printf ("0");
We now finish this block of code, and we go back to the for loop. Now, on following iterations, we will execute the third block of code (the --c). So c == 30. Then, we will run the middle section, and verify that we still meet the conditions to execute this loop.
}
I imagine the remainder of the program is not interesting.
printf("\n");
return 0;
}
Now, what does this code actually do?
So this code as a whole attempts to print the binary representation of a number. It assumes a few things, including that the number fits in an integer, and the system's integers are 32 bits.
More generally, in each loop of the for loop, we grab the last bit of the number that we haven't seen yet, and print 1 if that bit is high.
If you don't know binary notation yet, then that is something that you really need to learn to have this code make any sense.
The statement
k = n >> c;
right shift n to c bits. The expression k & 1 in if returns 1 if the last bit of k is 1 else it returns 0. Taking n = 8 and c = 7, see the example (assuming 8 bit representation):
iteration print
--------- -----
1. k = 0000 1000 >> 7 = 0000 0000
0000 0000 & 0000 0001 = 0000 0000 = 0 ==> 0
2. k = 0000 1000 >> 6 = 0000 0000
0000 0000 & 0000 0001 = 0000 0000 = 0 ==> 0
3. k = 0000 1000 >> 5 = 0000 0000
0000 0000 & 0000 0001 = 0000 0000 = 0 ==> 0
4. k = 0000 1000 >> 4 = 0000 0000
0000 0000 & 0000 0001 = 0000 0000 = 0 ==> 0
5. k = 0000 1000 >> 3 = 0000 0001
0000 0001 & 0000 0001 = 0000 0000 = 0 ==> 1
. ..
. ..
8. k = 0000 1000 >> 0 = 0000 0000
0000 0000 & 0000 0001 = 0000 0000 = 0 ==> 0

How can I get the value of the least significant bit in a number?

I'm working on a programming project and one of things I need to do is write a function that returns a mask that marks the value of the least significant 1 bit. Any ideas on how I can determine the value using bitwise operators?
ex:
0000 0000 0000 0000 0000 0000 0110 0000 = 96
What can I do with the # 96 to turn it into:
0000 0000 0000 0000 0000 0000 0010 0000 = 32
I've been slamming my head against the wall for hours trying to figure this out any help would be greatly appreciated!
x &= -x; /* clears all but the lowest bit of x */
A more readable code:
int leastSignificantBit(int number)
{
int index = 0;
while ((~number) & 1) {
number >>= 1;
index++;
}
return 1 << index;
}
To be sure you get the right bit/value:
The value at the least significant bit position = x & 1
The value of the isolated least significant 1 = x & -x
The zero-based index of the isolated least significant 1 = log2(x & -x)
Here's how it looks in JavaScript:
let x = 0b1101000;
console.log(x & 1); // 0 (the farthest-right bit)
console.log(x & -x); // 8 (the farthest-right 1 by itself)
console.log(Math.log2(x & -x); // 3 (the zero-based index of the farthest-right 1)

Resources