Matching bits algorithm - bit-manipulation

I have a problem wherein I need to find the number of matching bits (from left to right) between two integers
Inputs: 2 Variable A and B to store my decimal numbers
Output: Numbers of bits in A and B that match (starting from the left)
Some Examples:
A = 3 and B = 2, A and B bits match up to 7 bits from the left bit
A = 3 and B = 40, A and B bits match up to 7 bits from the left bit.
How can I do that using bitwise operation (AND,OR,XOR)?
Thanks

XOR the two together (to produce a number which has all zeroes from the left until the first non matching element), then shift the result right until it equals 0. Subtract this from the bit length of the integers you are dealing with (e.g., you seem to be implying 8 bits).
pseudocode:
int matchingBits(A, B) {
result = A XOR B
int shifts = 0
while (result != 0) {
result = result >> 1 (Shift right the result by 1)
shifts++
}
return integer_bit_length - shifts
}

Do (A XNOR B) to find the matching digits:
10101010
01001011
--XNOR--
00011101
Then use the hamming algorithm to count the ones: Count number of 1's in binary representation
(btw: xnor is !xor)

try this may be it will work
int matchingBitsCount(val1,val2)
{
int i , cnt = 0;
for(i=7;i>=0;i--)
{
if(((1<<i)&a)^((1<<i)&b))==0) //left shifted for starting from left side and then XOR
{
cnt++;
}
else
{
break;
}
}
}
i take val1 and val 2 as char if you want to check for int then just take i=31

Related

How shifting operator works in finding number of different bit in two integer?

i was trying to find out number of different bit in two number. i find a solution here but couldn't understand how it works.it right shifting with i and and doing and with 1. actually what is happening behind it? and why do loop through 32?
void solve(int A, int B)
{
int count = 0;
// since, the numbers are less than 2^31
// run the loop from '0' to '31' only
for (int i = 0; i < 32; i++) {
// right shift both the numbers by 'i' and
// check if the bit at the 0th position is different
if (((A >> i) & 1) != ((B >> i) & 1)) {
count++;
}
}
cout << "Number of different bits : " << count << endl;
}
The loop runs from 0 up to and including 31 (not through 32) because these are all of the possible bits that comprise a 32-bit integer and we need to check them all.
Inside the loop, the code
if (((A >> i) & 1) != ((B >> i) & 1)) {
count++;
}
works by shifting each of the two integers rightward by i (cutting off bits if i > 0), extracting the rightmost bit after the shift (& 1) and checking that they're the same (i.e. both 0 or both 1).
Let's walk through an example: solve(243, 2182). In binary:
243 = 11110011
2182 = 100010000110
diff bits = ^ ^^^ ^ ^
int bits = 00000000000000000000000000000000
i = 31 0
<-- loop direction
The indices of i that yield differences are 0, 2, 4, 5, 6 and 11 (we check from the right to the left--in the first iteration, i = 0 and nothing gets shifted, so & 1 gives us the rightmost bit, etc). The padding to the left of each number is all 0s in the above example.
Also, note that there are better ways to do this without a loop: take the XOR of the two numbers and run a popcount on them (count the bits that are set):
__builtin_popcount(243 ^ 2182); // => 6
Or, more portably:
std::bitset<CHAR_BIT * sizeof(int)>(243 ^ 2182).count()
Another note: best to avoid using namespace std;, return a value instead of producing a print side effect and give the method a clearer name than solve, for example bit_diff (I realize this is from geeksforgeeks).

Flipping a bit and to tell the number of bits remain same after flipping

I am confused by the below question.
Flipping a bit means changing the bit from 0 to 1 and vice versa.An operation OP(i) would result in flipping of binary digit as follows.
Performing OP(i) would result in flipping of each ith bit from starting i>0
An n bit number is given as input and OP(j) and OP(k) are applied on it one after the other. Objective is to specify how many bits will remain the same after applying these two operations.
When I have applied the logic floor(n/i)+floor(n/j)-2 it doesn't give me the expected solution.
example:
binary number:10110101101
i:3
j:4
expected output:6
But I got 3.Please tell me how to approach this problem.
I have also checked this solution Filpping bits in binary number .But they have also mentioned the same logic.
Let the register comprises of N bits, bits 1 to N.
(1) OP(i) implies every ith bit is flipped. That is bits at i, 2*i, 3*i ...
are flipped. Total bits flipped = floor(N/i)
(2) OP(j) implies every ith bit is flipped. That is bits at j, 2*j, 3*j ...
are flipped. Total bits flipped = floor(N/j)
(3) Let L = LCM(i,j). Therefore, bits at L, 2*L, 3*L, ... will be
flipped twice, implies bits unchanged are floor(N/L)
So, after OP(i) and OP(j), the total bits changed will be
floor(N/i) + floor(N/j) - 2*floor(N/L)
Number of bits unchanged = N - floor(N/i) - floor(N/j) + 2*floor(N/L)
For N=11, i=4, j=3, L = LCM(3,4) = 12,
Number of unchanged bits = 11 - 11/4 - 11/3 + 11/12 = 11 - 2 - 3 + 0 = 6
public static int nochange_bits(String input1,int i1,int i2)
{
try{
int len=input1.length();
if(i1<1 || i2<1){
return -1;
}else if(i1>len && i2>len){
return len;
}else if(i1==i2){
return len;
}else{
return (int)(len-Math.floor(len/i1)-Math.floor(len/i2)+2*Math.floor(len/(Math.abs(i1*i2) / GCF(i1, i2))));
}
}catch(Exception e){
e.printStackTrace();
return -1;
}
}
public static int GCF(int a, int b) {
if (b == 0) return a;
else return (GCF (b, a % b));
}
a) First, we check for all the conditions and invalidity of inputs
b) Then we calculate the LCM to get the output
Explanation: It's similar to the flipping switches problem,
first turn we switch the i1 bits
second turn we switch the i2 bits
in the process, the bits which have the LCM(i1,i2) are turned back.
so we add the lcm back to the total

Calculating the next higher number which has same number of set bits?

A solution is given to this question on geeksforgeeks website.
I wish to know does there exist a better and a simpler solution? This is a bit complicated to understand. Just an algorithm will be fine.
I am pretty sure this algorithm is as efficient and easier to understand than your linked algorithm.
The strategy here is to understand that the only way to make a number bigger without increasing its number of 1's is to carry a 1, but if you carry multiple 1's then you must add them back in.
Given a number 1001 1100
Right shift it until the value is odd, 0010 0111. Remember the number of shifts: shifts = 2;
Right shift it until the value is even, 0000 0100. Remember the number of shifts performed and bits consumed. shifts += 3; bits = 3;
So far, we have taken 5 shifts and 3 bits from the algorithm to carry the lowest digit possible. Now we pay it back.
Make the rightmost bit 1. 0000 0101. We now owe it 2 bits. bits -= 1
Shift left 3 times to add the 0's. 0010 1000. We do it three times because shifts - bits == 3 shifts -= 3
Now we owe the number two bits and two shifts. So shift it left twice, setting the leftmost bit to 1 each time. 1010 0011. We've paid back all the bits and all the shifts. bits -= 2; shifts -= 2; bits == 0; shifts == 0
Here's a few other examples... each step is shown as current_val, shifts_owed, bits_owed
0000 0110
0000 0110, 0, 0 # Start
0000 0011, 1, 0 # Shift right till odd
0000 0000, 3, 2 # Shift right till even
0000 0001, 3, 1 # Set LSB
0000 0100, 1, 1 # Shift left 0's
0000 1001, 0, 0 # Shift left 1's
0011 0011
0011 0011, 0, 0 # Start
0011 0011, 0, 0 # Shift right till odd
0000 1100, 2, 2 # Shift right till even
0000 1101, 2, 1 # Set LSB
0001 1010, 1, 1 # Shift left 0's
0011 0101, 0, 0 # Shift left 1's
There is a simpler, though definitely less efficient one. It follows:
Count the number of bits in your number (right shift your number until it reaches zero, and count the number of times the rightmost bit is 1).
Increment the number until you get the same result.
Of course it is extremely inefficient. Consider a number that's a power of 2 (having 1 bit set). You'll have to double this number to get your answer, incrementing the number by 1 in each iteration. Of course it won't work.
If you want a simpler efficient algorithm, I don't think there is one. In fact, it seems pretty simple and straightforward to me.
Edit: By "simpler", I mean it's mpre straightforward to implement, and possibly has a little less code lines.
Based on some code I happened to have kicking around which is quite similar to the geeksforgeeks solution (see this answer: https://stackoverflow.com/a/14717440/1566221) and a highly optimized version of #QuestionC's answer which avoids some of the shifting, I concluded that division is slow enough on some CPUs (that is, on my Intel i5 laptop) that looping actually wins out.
However, it is possible to replace the division in the g-for-g solution with a shift loop, and that turned out to be the fastest algorithm, again just on my machine. I'm pasting the code here for anyone who wants to test it.
For any implementation, there are two annoying corner cases: one is where the given integer is 0; the other is where the integer is the largest possible value. The following functions all have the same behaviour: if given the largest integer with k bits, they return the smallest integer with k bits, thereby restarting the loop. (That works for 0, too: it means that given 0, the functions return 0.)
Bit-hack solution with division:
template<typename UnsignedInteger>
UnsignedInteger next_combination_1(UnsignedInteger comb) {
UnsignedInteger last_one = comb & -comb;
UnsignedInteger last_zero = (comb + last_one) &~ comb;
if (last_zero)
return comb + last_one + ((last_zero / last_one) >> 1) - 1;
else if (last_one)
return UnsignedInteger(-1) / last_one;
else
return 0;
}
Bit-hack solution with division replaced by a shift loop
template<typename UnsignedInteger>
UnsignedInteger next_combination_2(UnsignedInteger comb) {
UnsignedInteger last_one = comb & -comb;
UnsignedInteger last_zero = (comb + last_one) &~ comb;
UnsignedInteger ones = (last_zero - 1) & ~(last_one - 1);
if (ones) while (!(ones & 1)) ones >>= 1;
comb += last_one;
if (comb) comb += ones >> 1; else comb = ones;
return comb;
}
Optimized shifting solution
template<typename UnsignedInteger>
UnsignedInteger next_combination_3(UnsignedInteger comb) {
if (comb) {
// Shift the trailing zeros, keeping a count.
int zeros = 0; for (; !(comb & 1); comb >>= 1, ++zeros);
// Adding one at this point turns all the trailing ones into
// trailing zeros, and also changes the 0 before them into a 1.
// In effect, this is steps 3, 4 and 5 of QuestionC's solution,
// without actually shifting the 1s.
UnsignedInteger res = comb + 1U;
// We need to put some ones back on the end of the value.
// The ones to put back are precisely the ones which were at
// the end of the value before we added 1, except we want to
// put back one less (because the 1 we added counts). We get
// the old trailing ones with a bit-hack.
UnsignedInteger ones = comb &~ res;
// Now, we finish shifting the result back to the left
res <<= zeros;
// And we add the trailing ones. If res is 0 at this point,
// we started with the largest value, and ones is the smallest
// value.
if (res) res += ones >> 1;
else res = ones;
comb = res;
}
return comb;
}
(Some would say that the above is yet another bit-hack, and I won't argue.)
Highly non-representative benchmark
I tested this by running through all 32-bit numbers. (That is, I create the smallest pattern with i ones and then cycle through all the possibilities, for each value of i from 0 to 32.):
#include <iostream>
int main(int argc, char** argv) {
uint64_t count = 0;
for (int i = 0; i <= 32; ++i) {
unsigned comb = (1ULL << i) - 1;
unsigned start = comb;
do {
comb = next_combination_x(comb);
++count;
} while (comb != start);
}
std::cout << "Found " << count << " combinations; expected " << (1ULL << 32) << '\n';
return 0;
}
The result:
1. Bit-hack with division: 43.6 seconds
2. Bit-hack with shifting: 15.5 seconds
3. Shifting algorithm: 19.0 seconds

Explanation for a line of code in c++ related to bitshifts

I don't want someone to explain how the following code works (it checks whether an int is pandigital) as I should be doing that myself. I just need help understanding line 8 specifically. I don't know what the | is doing.
private bool isPandigital(long n) {
int digits = 0;
int count = 0;
int tmp;
while (n > 0) {
tmp = digits;
digits = digits | 1 << (int)((n % 10) - 1);
if (tmp == digits) {
return false;
}
count++;
n /= 10;
}
return digits == (1 << count) - 1;
}
I know others have already explained that it's a bitwise OR, but I'd like to give my own interpretation.
digits = digits | X will copy all the 1 bits from X into digits.
digits = digits | 1 << Y will "set" a single bit in digits - it will set the Yth bit.
So, each loop sets a bit in digits.
| is bitwise or. But the code checks whether an int of length n has all digits 1..n. This is different from palindrome check. That line sets's (i-1)'th bit of digits to 1 if the last digit of n is i. [BTW, the code is wrong: if n contains a zero-digit, that line will trigger "undefined behavior": shifting an integer by a negative amount gives an undefined result.]
The code uses an integer digits to represent a set of digits. You can learn more about the technique by searching for bit sets.
It appears to be performing a Bitwise Or.
| is a bitwise OR
A bitwise OR takes two bit patterns of equal length and performs the logical inclusive OR operation on each pair of corresponding bits. The result in each position is 1 if the first bit is 1 OR the second bit is 1 OR both bits are 1; otherwise, the result is 0.
Example:
10010000
01010000
--------
11010000
http://en.wikipedia.org/wiki/Bitwise_operation
| is a bitwise or.
So the line is doing digits = digits | (1 << (int)((n % 10) - 1));

Find count of overlapping 1 bits

I'm trying to find the number of overlapping 1 bits between 2 given numbers.
For example, given 5 and 6:
5 // 101
6 // 110
There is 1 overlapping 1 bit (the first bit)
I have following code
#include <iostream>
using namespace std;
int main() {
int a,b;
int count = 0;
cin >> a >> b;
while (a & b != 0) {
count++;
a >>= 1;
b >>= 1;
}
cout << count << endl;
return 0;
}
But when I entered 335 and 123 it returned 7 but I think it is not correct
Can someone see a problem with my code?
The problem is that you're just printing out the number of times any of the bits match, as you lop off the least significant bit for each iteration (which will at max be the number of bits set for the smaller number). You're comparing all bits of [a] BITWISE AND [b] each iteration. You could rectify this by masking with 1: a & b & 1, so that while you're shift thing bits rightward each time, you're only checking if the least significant bit is being checked:
while (a && b){
count += a & b & 1;
a>>=1;
b>>=1;
}
Your existing algorithm counts each bit as long as any bit in the remaining bits to test matches; since 123 and 335 have a common MSB, it's true as long as either number is non-zero. 123 is the smaller with 7 bits, so it's true 7 times until that number is completely processed. As an extreme case, 128 (10000000) and 255 (11111111) would return 8 with your method, even though it's actually 1.
You want to AND the two numbers together to start with and then count the number of 1s in that result
You want to count the number of bits that are set. Instead, your code is sort of computing the binary logarithm.
Only increment the count if the lowest order bit is set.
for (int c = a & b; c != 0; c >>= 1) {
if (c & 1)
++count;
}
Slightly shorter form:
int countCommonBits(int a,int b) {
int n = 0;
for (unsigned v = (unsigned)(a & b); v; v >>= 1) {
n += 1 & v;
}
return n;
}
If you know both numbers are positive, you can omit the use of the unsigned type. Note when using "int" that sign extension on a right shift of a negative number would give you a bit of an overcount (i.e. an infinite loop).
Much later...
Reviewing an old answer, came across this. The current "accepted" answer is 1) inefficient, and 2) an infinite loop if the numbers are negative. FWIW.