count number of ones in a given integer using only << >> + | & ^ ~ ! = [duplicate] - c

This question already has answers here:
Count the number of set bits in a 32-bit integer
(65 answers)
Closed 7 years ago.
How to write a C program using only << >> + | & ^ ~ ! =
That counts the number of ones in a given integer?

Have a look at the Bit Twiddling hacks from Stanford. Here are some choices for your problem:
The naïve Approach
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; v >>= 1)
{
c += v & 1;
}
With a Lookup Table
static const unsigned char BitsSetTable256[256] =
{
# define B2(n) n, n+1, n+1, n+2
# define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
# define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
B6(0), B6(1), B6(1), B6(2)
};
unsigned int v; // count the number of bits set in 32-bit value v
unsigned int c; // c is the total bits set in v
// Option 1:
c = BitsSetTable256[v & 0xff] +
BitsSetTable256[(v >> 8) & 0xff] +
BitsSetTable256[(v >> 16) & 0xff] +
BitsSetTable256[v >> 24];
// Option 2:
unsigned char * p = (unsigned char *) &v;
c = BitsSetTable256[p[0]] +
BitsSetTable256[p[1]] +
BitsSetTable256[p[2]] +
BitsSetTable256[p[3]];
// To initially generate the table algorithmically:
BitsSetTable256[0] = 0;
for (int i = 0; i < 256; i++)
{
BitsSetTable256[i] = (i & 1) + BitsSetTable256[i / 2];
}
Brian W. Kernighan's Approach
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}
There are some more algorithms, read the linked page for details.

It is impossible to do this using only << >> + | & ^ ~ ! =. You need some other punctuation such as {, }, (, ) and ;, and you need some letters too.
Here is a solution without digits:
int bc(unsigned int n){int c=!&n;while(n){c++;n&=n+~!&n;}return c;}
It uses only the operators mentioned, but only works on 2's complement architectures.
If you cannot use if, for nor while statements, the parallel sum works this way:
int bitcount32(unsigned int x) {
x = ((x >> 1) & 0x55555555) + (x & 0x55555555);
x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
x = ((x >> 4) & 0x0f0f0f0f) + (x & 0x0f0f0f0f);
x = ((x >> 8) & 0x00ff00ff) + (x & 0x00ff00ff);
return (x >> 16) + (x & 0x0000ffff);
}
This function works for 32 bit ints, but can be modified to handle 16 or 64 bit ints. There are more compact solutions and possibly more efficient ones depending on your actual CPU performance here: How to count the number of set bits in a 32-bit integer?

Related

How to interleave 2 booleans using bitwise operators?

Suppose I have two 4-bit values, ABCD and abcd. How to interleave it, so it becomes AaBbCcDd, using bitwise operators? Example in pseudo-C:
nibble a = 0b1001;
nibble b = 0b1100;
char c = foo(a,b);
print_bits(c);
// output: 0b11010010
Note: 4 bits is just for illustration, I want to do this with two 32bit ints.
This is called the perfect shuffle operation, and it's discussed at length in the Bible Of Bit Bashing, Hacker's Delight by Henry Warren, section 7-2 "Shuffling Bits."
Assuming x is a 32-bit integer with a in its high-order 16 bits and b in its low-order 16 bits:
unsigned int x = (a << 16) | b; /* put a and b in place */
the following straightforward C-like code accomplishes the perfect shuffle:
x = (x & 0x0000FF00) << 8 | (x >> 8) & 0x0000FF00 | x & 0xFF0000FF;
x = (x & 0x00F000F0) << 4 | (x >> 4) & 0x00F000F0 | x & 0xF00FF00F;
x = (x & 0x0C0C0C0C) << 2 | (x >> 2) & 0x0C0C0C0C | x & 0xC3C3C3C3;
x = (x & 0x22222222) << 1 | (x >> 1) & 0x22222222 | x & 0x99999999;
He also gives an alternative form which is faster on some CPUs, and (I think) a little more clear and extensible:
unsigned int t; /* an intermediate, temporary variable */
t = (x ^ (x >> 8)) & 0x0000FF00; x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F0; x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C; x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x22222222; x = x ^ t ^ (t << 1);
I see you have edited your question to ask for a 64-bit result from two 32-bit inputs. I'd have to think about how to extend Warren's technique. I think it wouldn't be too hard, but I'd have to give it some thought. If someone else wanted to start here and give a 64-bit version, I'd be happy to upvote them.
EDITED FOR 64 BITS
I extended the second solution to 64 bits in a straightforward way. First I doubled the length of each of the constants. Then I added a line at the beginning to swap adjacent double-bytes and intermix them. In the following 4 lines, which are pretty much the same as the 32-bit version, the first line swaps adjacent bytes and intermixes, the second line drops down to nibbles, the third line to double-bits, and the last line to single bits.
unsigned long long int t; /* an intermediate, temporary variable */
t = (x ^ (x >> 16)) & 0x00000000FFFF0000ull; x = x ^ t ^ (t << 16);
t = (x ^ (x >> 8)) & 0x0000FF000000FF00ull; x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F000F000F0ull; x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0Cull; x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x2222222222222222ull; x = x ^ t ^ (t << 1);
From Stanford "Bit Twiddling Hacks" page:
https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableObvious
uint32_t x = /*...*/, y = /*...*/;
uint64_t z = 0;
for (int i = 0; i < sizeof(x) * CHAR_BIT; i++) // unroll for more speed...
{
z |= (x & 1U << i) << i | (y & 1U << i) << (i + 1);
}
Look at the page they propose different and faster algorithms to achieve the same.
Like so:
#include <limits.h>
typedef unsigned int half;
typedef unsigned long long full;
full mix_bits(half a,half b)
{
full result = 0;
for (int i=0; i<sizeof(half)*CHAR_BIT; i++)
result |= (((a>>i)&1)<<(2*i+1))|(((b>>i)&1)<<(2*i+0));
return result;
}
Here is a loop-based solution that is hopefully more readable than some of the others already here.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
uint64_t interleave(uint32_t a, uint32_t b) {
uint64_t result = 0;
int i;
for (i = 0; i < 31; i++) {
result |= (a >> (31 - i)) & 1;
result <<= 1;
result |= (b >> (31 - i)) & 1;
result <<= 1;
}
// Skip the last left shift.
result |= (a >> (31 - i)) & 1;
result <<= 1;
result |= (b >> (31 - i)) & 1;
return result;
}
void printBits(uint64_t a) {
int i;
for (i = 0; i < 64; i++)
printf("%lu", (a >> (63 - i)) & 1);
puts("");
}
int main(){
uint32_t a = 0x9;
uint32_t b = 0x6;
uint64_t c = interleave(a,b);
printBits(a);
printBits(b);
printBits(c);
}
I have used the 2 tricks/operations used in this post How do you set, clear, and toggle a single bit? of setting a bit at particular index and checking the bit at particular index.
The following code is implemented using these 2 operations only.
int a = 0b1001;
int b = 0b1100;
long int c=0;
int index; //To specify index of c
int bit,i;
//Set bits in c from right to left.
for(i=32;i>=0;i--)
{
index=2*i+1; //We have to add the bit in c at this index
//Check a
bit=a&(1<<i); //Checking whether the i-th bit is set in a
if(bit)
c|=1<<index; //Setting bit in c at index
index--;
//Check b
bit=b&(1<<i); //Checking whether the i-th bit is set in b
if(bit)
c|=1<<index; //Setting bit in c at index
}
printf("%ld",c);
Output: 210 which is 0b11010010

Hamming weight written only in binary operations?

I need to write an expression of one byte Hamming weight in terms of binary operations only (&, ^, >>); without any loop, just a formula.
I know that there are plenty algorithms, that allow computing Hamming weight, but all of them use arithmetical operations or looping.
If we take an algorithm from http://en.wikipedia.org/wiki/Hamming_weight, then the first sum D=B+C can be written as D = B^C^(B&C << 1), but two following sums are more complicated.
Does anyone have a hint?
UPDATE:
Thank you for help guys. Actually, I needed something like following:
int popcount_1(unsigned char in){
unsigned char m1 = 0x55;
unsigned char m2 = 0x33;
unsigned char m4 = 0x0f;
unsigned char B,C = 0;
unsigned char x = in;
x = (x & (x << 1) & (m1 << 1)) | (m1 & (x ^ (x >> 1)));
B = x & m2;
C = (x >> 2) & m2;
x = B ^ C ^ ((B & C) << 1);
B = (x & m4 ) ^ ((x >> 4) & m4);
C = (x & ((x >> 4) & m4)) << 1;
x = B ^ C ^ ((B & C) << 1);
return x;
}
This code will result in Hamming weight of variable in. It does not contain any +, -, or comparison instructions and it can work on 8bits microcontrollers.
Nevertheless, it takes more operations than most of other solutions. Now, I am trying to simplify it.
UPDATE2: Another solution, based on 64 bits registers, is proposed by #Evgeny Kluev
I think the best you can do is O(log n). Here is code (in Go) for the pop-count of a 32-bit integer. Extending this to 64-bits should be obvious if you need it, hopefully the comments make it clear what is actually going on:
func popCount(n uint32) int {
// each bit in n is a one-bit integer that indicates how many bits are set
// in that bit.
n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555)
// Now every two bits are a two bit integer that indicate how many bits were
// set in those two bits in the original number
n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333)
// Now we're at 4 bits
n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F)
// 8 bits
n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF)
// 16 bits
n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF)
// kaboom - 32 bits
return int(n)
}
I'm not sure if this is what you search for, but here is just a formula using only shifts and bitwise and:
int weight(unsigned char x)
{
return ((0x876543210 >>
(((0x4332322132212110 >> ((x & 0xF) << 2)) & 0xF) << 2)) >>
((0x4332322132212110 >> (((x & 0xF0) >> 2)) & 0xF) << 2))
& 0xf;
}
Here shift operation is twice used as a substitute for array indexing (to find 4-bit hamming weights). And one more shift operation uses array indexing to perform addition.

How To Find The Leading Number Of Zero's In a Number using C

for example,if i have number 64,then its binary representation would be 0000 0000 0000 0000 0000 0000 0100 0000 so leading number of zero's is 25.
remember i have to calculate this in O(1) time.
please tell me the right way to do that.even if your complexity is >O(1) please do post your answer. thanx
I just found this problem at the top of the search results and this code:
int pop(unsigned x) {
unsigned n;
n = (x >> 1) & 033333333333;
x = x - n;
n = (n >> 1) & 033333333333;
x = x - n;
x = (x + (x >> 3)) & 030707070707;
return x % 63;
}
int nlz(unsigned x) {
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >>16);
return pop(~x);
}
where pop counts 1 bits, is several times faster than the first (upvoted) answer.
I didn't notice, question was about 64 bits numbers, so here:
int nlz(unsigned long x) {
unsigned long y;
long n, c;
n = 64;
c = 32;
do {
y = x >> c;
if (y != 0) {
n = n - c;
x = y;
}
c = c >> 1;
} while (c != 0);
return n - x;
}
is a 64 bits algorithm, again several times faster than the mentioned above.
See here for the 32-bit version and other great bit-twiddling hacks.
// this is like doing a sign-extension
// if original value was 0x00.01yyy..y
// then afterwards will be 0x00.01111111
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
x |= (x >> 32);
and after that you just need to return 64 - numOnes(x).
A simple way to do that is numOnes32(x) + numOnes32(x >> 32) where numOnes32 is defined as:
int numOnes32(unsigned int x) {
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return(x & 0x0000003f);
}
I haven't tried out this code, but this should do numOnes64 directly (in less time):
int numOnes64(unsigned long int x) {
x = ((x >> 1) & 0x5555555555555555L) + (x & 0x5555555555555555L);
x = ((x >> 2) & 0x3333333333333333L) + (x & 0x3333333333333333L);
// collapse:
unsigned int v = (unsigned int) ((x >>> 32) + x);
v = ((v >> 4) + v) & 0x0f0f0f0f) + (v & 0x0f0f0f0f);
v = ((v >> 8) & 0x00ff00ff) + (v & 0x00ff00ff);
return ((v >> 16) & 0x0000ffff) + (v & 0x0000ffff);
}
Right shift is your friend.
int input = 64;
int sample = ( input < 0 ) ? 0 : input;
int leadingZeros = ( input < 0 ) ? 0 : 32;
while(sample) {
sample >>= 1;
--leadingZeros;
}
printf("Input = %d, leading zeroes = %d\n",input, leadingZeros);
I would go with:
unsigned long clz(unsigned long n) {
unsigned long result = 0;
unsigned long mask = 0;
mask = ~mask;
auto size = sizeof(n) * 8;
auto shift = size / 2;
mask >>= shift;
while (shift >= 1) {
if (n <= mask) {
result += shift;
n <<= shift;
}
shift /= 2;
mask <<= shift;
}
return result;
}
Because the logarithm base 2 roughly represents the number of bits required to represent a number, it might be useful in the answer:
irb(main):012:0> 31 - (Math::log(64) / Math::log(2)).floor()
=> 25
irb(main):013:0> 31 - (Math::log(65) / Math::log(2)).floor()
=> 25
irb(main):014:0> 31 - (Math::log(127) / Math::log(2)).floor()
=> 25
irb(main):015:0> 31 - (Math::log(128) / Math::log(2)).floor()
=> 24
Of course, one downside to using log(3) is that it is a floating-point routine; there are probably some supremely clever bit-tricks to find the number of leading zero bits in integers, but I can't think of one off the top of my head...
Using floating points is not the right answer....
Here is an algo that I use to count the TRAILING 0... change it for Leading...
This algo is in O(1) (will always execute in ~ the same time, or even the same time on some CPU).
int clz(unsigned int i)
{
int zeros;
if ((i&0xffff)==0) zeros= 16, i>>= 16; else zeroes= 0;
if ((i&0xff)==0) zeros+= 8, i>>= 8;
if ((i&0xf)==0) zeros+= 4, i>>= 4;
if ((i&0x3)==0) zeros+= 2, i>>= 2;
if ((i&0x1)==0) zeros+= 1, i>>= 1;
return zeroes+i;
}

reverse the bits using bit field in c language?

how to reverse the bits using bit wise operators in c language
Eg:
i/p: 10010101
o/p: 10101001
If it's just 8 bits:
u_char in = 0x95;
u_char out = 0;
for (int i = 0; i < 8; ++i) {
out <<= 1;
out |= (in & 0x01);
in >>= 1;
}
Or for bonus points:
u_char in = 0x95;
u_char out = in;
out = (out & 0xaa) >> 1 | (out & 0x55) << 1;
out = (out & 0xcc) >> 2 | (out & 0x33) << 2;
out = (out & 0xf0) >> 4 | (out & 0x0f) << 4;
figuring out how the last one works is an exercise for the reader ;-)
Knuth has a section on Bit reversal in The Art of Computer Programming Vol 4A, bitwise tricks and techniques.
To reverse the bits of a 32 bit number in a divide and conquer fashion he uses magic constants
u0= 1010101010101010, (from -1/(2+1)
u1= 0011001100110011, (from -1/(4+1)
u2= 0000111100001111, (from -1/(16+1)
u3= 0000000011111111, (from -1/(256+1)
Method credited to Henry Warren Jr., Hackers delight.
unsigned int u0 = 0x55555555;
x = (((x >> 1) & u0) | ((x & u0) << 1));
unsigned int u1 = 0x33333333;
x = (((x >> 2) & u1) | ((x & u1) << 2));
unsigned int u2 = 0x0f0f0f0f;
x = (((x >> 4) & u2) | ((x & u2) << 4));
unsigned int u3 = 0x00ff00ff;
x = (((x >> 8) & u3) | ((x & u3) << 8));
x = ((x >> 16) | (x << 16) mod 0x100000000); // reversed
The 16 and 8 bit cases are left as an exercise to the reader.
Well, this might not be the most elegant solution but it is a solution:
int reverseBits(int x) {
int res = 0;
int len = sizeof(x) * 8; // no of bits to reverse
int i, shift, mask;
for(i = 0; i < len; i++) {
mask = 1 << i; //which bit we are at
shift = len - 2*i - 1;
mask &= x;
mask = (shift > 0) ? mask << shift : mask >> -shift;
res |= mask; // mask the bit we work at at shift it to the left
}
return res;
}
Tested it on a sheet of paper and it seemed to work :D
Edit: Yeah, this is indeed very complicated. I dunno why, but I wanted to find a solution without touching the input, so this came to my haead

Reverse bit pattern in C

I am converting a number to binary and have to use putchar to output each number.
The problem is that I am getting the order in reverse.
Is there anyway to reverse a numbers bit pattern before doing my own stuff to it?
As in int n has a specific bit pattern - how can I reverse this bit pattern?
There are many ways to do this, some very fast. I had to look it up.
Reverse bits in a byte
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
Reverse an N-bit quantity in parallel in 5 * lg(N) operations:
unsigned int v; // 32-bit word to reverse bit order
// swap odd and even bits
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
// swap consecutive pairs
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
// swap nibbles ...
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
// swap bytes
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
// swap 2-byte long pairs
v = ( v >> 16 ) | ( v << 16);
Reverse bits in word by lookup table
static const unsigned char BitReverseTable256[256] =
{
# define R2(n) n, n + 2*64, n + 1*64, n + 3*64
# define R4(n) R2(n), R2(n + 2*16), R2(n + 1*16), R2(n + 3*16)
# define R6(n) R4(n), R4(n + 2*4 ), R4(n + 1*4 ), R4(n + 3*4 )
R6(0), R6(2), R6(1), R6(3)
};
unsigned int v; // reverse 32-bit value, 8 bits at time
unsigned int c; // c will get v reversed
// Option 1:
c = (BitReverseTable256[v & 0xff] << 24) |
(BitReverseTable256[(v >> 8) & 0xff] << 16) |
(BitReverseTable256[(v >> 16) & 0xff] << 8) |
(BitReverseTable256[(v >> 24) & 0xff]);
// Option 2:
unsigned char * p = (unsigned char *) &v;
unsigned char * q = (unsigned char *) &c;
q[3] = BitReverseTable256[p[0]];
q[2] = BitReverseTable256[p[1]];
q[1] = BitReverseTable256[p[2]];
q[0] = BitReverseTable256[p[3]];
Please look at http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel for more information and references.
Pop bits off your input and push them onto your output. Multiplying and dividing by 2 are the push and pop operations. In pseudo-code:
reverse_bits(x) {
total = 0
repeat n times {
total = total * 2
total += x % 2 // modulo operation
x = x / 2
}
return total
}
See modulo operation on Wikipedia if you haven't seen this operator.
Further points:
What would happen if you changed 2 to 4? Or to 10?
How does this effect the value of n? What is n?
How could you use bitwise operators (<<, >>, &) instead of divide and modulo? Would this make it faster?
Could we use a different algorithm to make it faster? Could lookup tables help?
Let me guess: you have a loop that prints the 0th bit (n&1), then shifts the number right. Instead, write a loop that prints the 31st bit (n&0x80000000) and shifts the number left. Before you do that loop, do another loop that shifts the number left until the 31st bit is 1; unless you do that, you'll get leading zeros.
Reversing is possible, too. Somthing like this:
unsigned int n = 12345; //Source
unsigned int m = 0; //Destination
int i;
for(i=0;i<32;i++)
{
m |= n&1;
m <<= 1;
n >>= 1;
}
I know: that is not exactly C, but I think that is an interesting answer:
int reverse(int i) {
int output;
__asm__(
"nextbit:"
"rcll $1, %%eax;"
"rcrl $1, %%ebx;"
"loop nextbit;"
: "=b" (output)
: "a" (i), "c" (sizeof(i)*8) );
return output;
}
The rcl opcode puts the shifted out bit in the carry flag, then rcr recovers that bit to another register in the reverse order.
My guess is that you have a integer and you're attempting to convert it to binary?
And the "answer" is ABCDEFG, but your "answer" is GFEDCBA?
If so, I'd double check the endian of the machine you're doing it on and the machine the "answer" came from.
Here are functions I've used to reverse bits in a byte and reverse bytes in a quad.
inline unsigned char reverse(unsigned char b) {
return (b&1 << 7)
| (b&2 << 5)
| (b&4 << 3)
| (b&8 << 1)
| (b&0x10 >> 1)
| (b&0x20 >> 3)
| (b&0x40 >> 5)
| (b&0x80 >> 7);
}
inline unsigned long wreverse(unsigned long w) {
return ( ( w &0xFF) << 24)
| ( ((w>>8) &0xFF) << 16)
| ( ((w>>16)&0xFF) << 8)
| ( ((w>>24)&0xFF) );
}

Resources