Detecting two numbers with same/matching bit pattern in their lower order bits - bit-manipulation

We've two numbers with same bit patterns in their lower order.
For ex: 01001110110 and 10110 are the two numbers, they match with their lower order.
Is there a simple way to find this out ?
I've a solution with shifting the bits and then comparing, Is there a better way ?

You can XOR them together and check if the last N lower order bits are all zero (where N is the number of bits in the smaller of the two numbers).
For eg: using the sample numbers you gave, 01001110110 and 10110:
01001110110 XOR 10110 = 01001100000
Notice that the last 5 bits are all zero in the result.
In C/C++/Java you can use the ^ operator for this purpose and then extract the last N bits with a mask like so:
int a = 0x276; // 01001110110
int b = 0x16; // 10110
if (((a ^ b) & 0x1F) == 0) { // Mask 0x1F assumes least significant 5 bits for match
// match!
}
If course, this assumes you know the number of significant bits in each number (5 in this example). If instead the number of matching bits is unspecified, you will need to count the number of consecutive trailing 0s to figure out how many bits match. There may be some other trickery you could perform in this case.

Mask the numbers with &:
if (number1 & 0x1f == number2 & 0x1f)

Related

how to count only 1bits in binary representation of number without loop

Suppose I have two numbers(minimum and maximum) . `
for example (0 and 9999999999)
maximum could be so huge. now I also have some other number. it could be between those minimum and maximum number. Let's say 15. now What I need to do is get all the multiples of 15(15,30,45 and so on, until it reaches the maximum number). and for each these numbers, I have to count how many 1 bits there are in their binary representations. for example, 15 has 4(because it has only 4 1bits).
The problem is, I need a loop in a loop to get the result. first loop is to get all multiples of that specific number(in our example it was 15) and then for each multiple, i need another loop to count only 1bits. My solution takes so much time. Here is how I do it.
unsigned long long int min = 0;
unsigned long long int max = 99999999;
unsigned long long int other_num = 15;
unsigned long long int count = 0;
unsigned long long int other_num_helper = other_num;
while(true){
if(other_num_helper > max) break;
for(int i=0;i<sizeof(int)*4;i++){
int buff = other_num_helper & 1<<i;
if(buff != 0) count++; //if bit is not 0 and is anything else, then it's 1bits.
}
other_num_helper+=other_num;
}
cout<<count<<endl;
Look at the bit patterns for the numbers between 0 and 2^3
000
001
010
011
100
101
110
111
What do you see?
Every bit is one 4 times.
If you generalize, you find that the numbers between 0 and 2^n have n*2^(n-1) bits set in total.
I am sure you can extend this reasoning for arbitrary bounds.
Here's how I do it for a 32 bit number.
std::uint16_t bitcount(
std::uint32_t n
)
{
register std::uint16_t reg;
reg = n - ((n >> 1) & 033333333333)
- ((n >> 2) & 011111111111);
return ((reg + (reg >> 3)) & 030707070707) % 63;
}
And the supporting comments from the program:
Consider a 3 bit number as being 4a + 2b + c. If we shift it right 1 bit, we have 2a + b. Subtracting this from the original gives 2a + b + c. If we right-shift the original 3-bit number by two bits, we get a, and so with another subtraction we have a + b + c, which is the number of bits in the original number.
The first assignment statement in the routine computes 'reg'. Each digit in the octal representation is simply the number of 1’s in the corresponding three bit positions in 'n'.
The last return statement sums these octal digits to produce the final answer. The key idea is to add adjacent pairs of octal digits together and then compute the remainder modulus 63.
This is accomplished by right-shifting 'reg' by three bits, adding it to 'reg' itself and ANDing with a suitable mask. This yields a number in which groups of six adjacent bits (starting from the LSB) contain the number of 1’s among those six positions in n. This number modulo 63 yields the final answer. For 64-bit numbers, we would have to add triples of octal digits and use modulus 1023.

parity of set bits after xor of two numbers

I found an observation by testing in C++.
Observation is ,
1 ) If two numbers where both numbers have odd number of set bits in it then its XOR will have even number of set bits in it.
2 ) If two numbers where both numbers have even number of set bits in it then its XOR will have even number of set bits in it.
1 ) If two numbers where one number has even number of set bits and another has odd number of set bits then its XOR will have odd number of set bits in it.
I could not prove it. I want to prove it. Please help me.
Code that i executed on my computer is
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int> vec[4];
for(int i=1;i<=100;i++){
for(int j=i+1;j<=100;j++){
int x=__builtin_popcount(i)%2;
int y=__builtin_popcount(j)%2;
int in=0;
in|=(x<<1);
in|=(y<<0);
int v=__builtin_popcount(i^j)%2;
vec[in].push_back(v);
}
}
for(int i=0;i<4;i++){
for(int j=0;j<vec[i].size();j++) cout<<vec[i][j] << " ";
cout << endl;
}
return 0;
}
It gives me
100 zeros in first line
100 ones in second line
100 ones in third line
100 zeros in fourth line
If there is a doubt in understanding the code then please tell me in comments.
This behavior mirrors an easy-to-prove arithmetical fact:
When you add two odd numbers, you get an even number,
When you add two even numbers, you get an even number,
When you add an odd number to an even number, you get an odd number.
With this fact in hand, consider the truth table of XOR, and note that for each of the four options in the table ({0, 0 => 0}, {0, 1 => 1}, {1, 0 => 1}, {1, 1, => 0}) the odd/even parity of the count of 1s remains invariant. In other words, if the input has an odd number of 1s, the output will have an odd number of 1s as well, and vice versa.
This observation explains why you observe the result: XORing two numbers with the counts of set bits of N and M will yield a number that has the same odd/even parity as N+M.
Thanks all who tried to answer.
We can give proof like this,
Suppose N is number of set bits in first number and M is set bits in second number.
Then set bits in XOR of these two numbers is N+M - 2 (Δ) where is delta is total number of bit positions where both of numbers have set bit. Now this expression explains every thing.
even + odd - even = odd
odd + odd - even = even
even + even - even = even
xor just clears out common bits. It doesn't matter how many bits are set, just how many bits are common.
With all bits common, the result is zero. With no bits in common, the result is the sum of set bits.
No conclusions based on parity of inputs unless you also account for parity of common bits.
A possible proof is based in the observation that xor is a conmutative opperator, so (xor digits of x) xor (xor digits of y) = xor of digits of (x xor y)

Shift left/right adding zeroes/ones and dropping first bits

I've got to program a function that receives
a binary number like 10001, and
a decimal number that indicates how many shifts I should perform.
The problem is that if I use the C++ operator <<, the zeroes are pushed from behind but the first numbers aren't dropped... For example
shifLeftAddingZeroes(10001,1)
returns 100010 instead of 00010 that is what I want.
I hope I've made myself clear =P
I assume you are storing that information in int. Take into consideration, that this number actually has more leading zeroes than what you see, ergo your number is most likely 16 bits, meaning 00000000 00000001 . Maybe try AND-ing it with number having as many 1 as the number you want to have after shifting? (Assuming you want to stick to bitwise operations).
What you want is to bit shift and then limit the number of output bits which can be active (hold a value of 1). One way to do this is to create a mask for the number of bits you want, then AND the bitshifted value with that mask. Below is a code sample for doing that, just replace int_type with the type of value your using -- or make it a template type.
int_type shiftLeftLimitingBitSize(int_type value, int numshift, int_type numbits=some_default) {
int_type mask = 0;
for (unsigned int bit=0; bit < numbits; bit++) {
mask += 1 << bit;
}
return (value << numshift) & mask;
}
Your output for 10001,1 would now be shiftLeftLimitingBitSize(0b10001, 1, 5) == 0b00010.
Realize that unless your numbits is exactly the length of your integer type, you will always have excess 0 bits on the 'front' of your number.

counting the number of bit required to represent an integer in 2's complement

I have to write a function that count the number of bit required to represent an int in 2's complement form. The requirement:
1. can only use: ! ~ & ^ | + << >>
2. no loops and conditional statement
3. at most, 90 operators are used
currently, I am thinking something like this:
int howManyBits(int x) {
int mostdigit1 = !!(0x80000000 & x);
int mostdigit2 = mostdigit1 | !!(0x40000000 & x);
int mostdigit3 = mostdigit2 | !!(0x20000000 & x);
//and so one until it reach the least significant digit
return mostdigit1+mostdigit2+...+mostdigit32+1;
}
However, this algorithm doesn't work. it also exceed the 90 operators limit. any suggestion, how can I fix and improve this algorithm?
With 2's complement integers, the problem are the negative numbers. A negative number is indicated by the most significant bit: If it is set, the number is negative.
The negative of a 2's complement integer n is defined as -(1's complement of n)+1.
Thus, I would first test for the negative sign. If it is set, the number of bits required is simply the number of bits available to represent an integer, e.g. 32 bits. If not, you can simply count the number of bits required by shifting repeatedly n by one bit right, until the result is zero. If n, e.g., would be +1, e.g. 000…001, you had to shift it once right to make the result zero, e.g. 1 times. Thus you need 1 bit to represent it.

Swapping pair of bits in a Byte

I have an arbitrary 8-bit binary number e.g., 11101101
I have to swap all the pair of bits like:
Before swapping: 11-10-11-01
After swapping: 11-01-11-10
I was asked this in an interview !
In pseudo-code:
x = ((x & 0b10101010) >> 1) | ((x & 0b01010101) << 1)
It works by handling the low bits and high bits of each bit-pair separately and then combining the result:
The expression x & 0b10101010 extracts the high bit from each pair, and then >> 1 shifts it to the low bit position.
Similarly the expression (x & 0b01010101) << 1 extracts the low bit from each pair and shifts it to the high bit position.
The two parts are then combined using bitwise-OR.
Since not all languages allow you to write binary literals directly, you could write them in for example hexadecimal:
Binary Hexadecimal Decimal
0b10101010 0xaa 170
0b01010101 0x55 85
Make two bit masks, one containing all the even bits and one containing the uneven bits (10101010 and 01010101).
Use bitwise-and to filter the input into two numbers, one having all the even bits zeroed, the other having all the uneven bits zeroed.
Shift the number that contains only even bits one bit to the left, and the other one one bit to the right
Use bitwise-or to combine them back together.
Example for 16 bits (not actual code):
short swap_bit_pair(short i) {
return ((i & 0101010110101010b) >> 1) | ((i & 0x0101010101010101b) << 1));
}
b = (a & 170 >> 1) | (a & 85 << 1)
The most elegant and flexible solution is, as others have said, to apply an 'comb' mask to both the even and odd bits seperately and then, having shifted them left and right respectively one place to combine them using bitwise or.
One other solution you may want to think about takes advantage of the relatively small size of your datatype. You can create a look up table of 256 values which is statically initialised to the values you want as output to your input:
const unsigned char lookup[] = { 0x02, 0x01, 0x03, 0x08, 0x0A, 0x09, 0x0B ...
Each value is placed in the array to represent the transformation of the index. So if you then do this:
unsigned char out = lookup[ 0xAA ];
out will contain 0x55
This is more cumbersome and less flexible than the first approach (what if you want to move from 8 bits to 16?) but does have the approach that it will be measurably faster if performing a large number of these operations.
Suppose your number is num.
First find the even position bit:
num & oxAAAAAAAA
Second step find the odd position bit:
num & ox55555555
3rd step change position odd position to even position bit and even position bit to odd position bit:
Even = (num & oxAAAAAAAA)>>1
Odd = (num & 0x55555555)<<1
Last step ... result = Even | Odd
Print result
I would first code it 'longhand' - that is to say in several obvious, explicit stages, and use that to validate that the unit tests I had in place were functioning correctly, and then only move to more esoteric bit manipulation solutions if I had a need for performance (and that extra performance was delivered by said improvments)
Code for people first, computers second.