Count the number of contiguous 1 bits from the left [closed] - c

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am stuck on this problem: Assume that we have 32-bit integer, write a C function to count the number of contiguous 1 bits, from the left. For example:
leftCount(0xFF000000) = 8
leftCount(0x0FFFFFFF) = 0 (because the number starts with 0)
leftCount(-1) = 32
In the function, I am allowed to use logical operators such as ! ~ & ^ | + << >>
No loop and condition structure is allowed.
Thanks

You can test if bit x is set in value y by evaluating y & (1 << x). It is zero if the bit is not set.
Using this, you can just loop from 31 down to 0, checking if each bit is set, stopping when your reach an unset bit. You should be able to code this yourself.
You can speed this up by binary searching. You can check if the first 16 bits are set by evaluating (y & 0xFFFF0000) == 0xFFFF0000. If it is, then you can check the next 8 bits in a similar manner; and if it is not, then you can check the first 8 bits. Recurse down using this method and you'll have a faster algorithm.

In GCC you can use a built-in function:
Built-in Function: int __builtin_clz (unsigned int x)
Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined.
You have to negate the input using binary negation: ~x (0 will become 1, and vice versa).
Here is a more academic solution:
#include <stdio.h>
#include <stdint.h>
int leftCount (unsigned int value) {
if (~value == 0) {
return 32; // you said your ints were 32 bits, so the code assumes that
}
int result = 0;
while (value >> 31 == 1) { // test if highest bit is set
value <<= 1; // shift the input to the left
++result; // one more bit was seen
}
return result;
}
int main (void) {
unsigned int value;
while (scanf ("%i", &value) == 1) {
printf ("leftCount(0x%x) == %u\n", value, leftCount(value));
}
return 0;
}

There is a fast function to count the number of leading zeros, and it's easy to transform this problem to that: complement the input.
int leftCount = input == 0 ? 0 : __builtin_clz(~input);
There's not even an algorithm there.

I found myself a solution on the Internet. But my requirement is to use not more than 50 logical operators, so anybody help me optimize this function, please.
int bit_count_from_left(int x) {
/* Shift every bit to the rightmost bit and & it with 1, then start from the leftmost bit and determine
* whether a given bit and all the bits to its left are set to 1. */
int lb01 = ((x >> 31) & 1); int lb02 = ((x >> 30) & 1); int lb03 = ((x >> 29) & 1);
int lb04 = ((x >> 28) & 1); int lb05 = ((x >> 27) & 1); int lb06 = ((x >> 26) & 1);
int lb07 = ((x >> 25) & 1); int lb08 = ((x >> 24) & 1); int lb09 = ((x >> 23) & 1);
int lb10 = ((x >> 22) & 1); int lb11 = ((x >> 21) & 1); int lb12 = ((x >> 20) & 1);
int lb13 = ((x >> 19) & 1); int lb14 = ((x >> 18) & 1); int lb15 = ((x >> 17) & 1);
int lb16 = ((x >> 16) & 1); int lb17 = ((x >> 15) & 1); int lb18 = ((x >> 14) & 1);
int lb19 = ((x >> 13) & 1); int lb20 = ((x >> 12) & 1); int lb21 = ((x >> 11) & 1);
int lb22 = ((x >> 10) & 1); int lb23 = ((x >> 9) & 1); int lb24 = ((x >> 8) & 1);
int lb25 = ((x >> 7) & 1); int lb26 = ((x >> 6) & 1); int lb27 = ((x >> 5) & 1);
int lb28 = ((x >> 4) & 1); int lb29 = ((x >> 3) & 1); int lb30 = ((x >> 2) & 1);
int lb31 = ((x >> 1) & 1); int lb32 = ((x) & 1);
int bool01 = lb01; int bool02 = bool01 & lb02; int bool03 = bool02 & lb03;
int bool04 = bool03 & lb04; int bool05 = bool04 & lb05; int bool06 = bool05 & lb06;
int bool07 = bool06 & lb07; int bool08 = bool07 & lb08; int bool09 = bool08 & lb09;
int bool10 = bool09 & lb10; int bool11 = bool10 & lb11; int bool12 = bool11 & lb12;
int bool13 = bool12 & lb13; int bool14 = bool13 & lb14; int bool15 = bool14 & lb15;
int bool16 = bool15 & lb16; int bool17 = bool16 & lb17; int bool18 = bool17 & lb18;
int bool19 = bool18 & lb19; int bool20 = bool19 & lb20; int bool21 = bool20 & lb21;
int bool22 = bool21 & lb22; int bool23 = bool22 & lb23; int bool24 = bool23 & lb24;
int bool25 = bool24 & lb25; int bool26 = bool25 & lb26; int bool27 = bool26 & lb27;
int bool28 = bool27 & lb28; int bool29 = bool28 & lb29; int bool30 = bool29 & lb30;
int bool31 = bool30 & lb31; int bool32 = bool31 & lb32;
int result = bool01 + bool02 + bool03 + bool04 + bool05 + bool06 + bool07 + bool08 + bool09 + bool10
+ bool11 + bool12 + bool13 + bool14 + bool15 + bool16 + bool17 + bool18 + bool19 + bool20
+ bool21 + bool22 + bool23 + bool24 + bool25 + bool26 + bool27 + bool28 + bool29 + bool30
+ bool31 + bool32;
return result;
}

Spoiler:
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
unsigned naive_leading1bit_count(uint32_t val)
{
unsigned cnt;
for (cnt=0; val & (1u << (sizeof val*CHAR_BIT-1)); val <<=1 ) {
cnt += 1;
}
return cnt;
}
int main(void)
{
unsigned res;
uint32_t uuu;
for (uuu = 0xf; uuu; uuu <<=1) {
res = naive_leading1bit_count( uuu );
printf("%x: %u\n", uuu, res);
}
return 0;
}

Related

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

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?

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

number of consecutive ones on the left side of an integer using only bit operations

How do I return the number of consecutive ones on the left side of an integer using only bit operations in C (no if, for, while,etc.)?
I'm not sure where to begin for this problem.
//BurstSize(-1) = 32,
//BurstSize(0xFFF0F0F0) = 12
//Legal: ! ~ & ^ | + << >>
//Max ops: 50
int BurstSize(int a) {
//code
}
If you use GCC, you could call __builtin_clz() to count leading zeros. Invert the input, then it could be used to count leading ones.
int BurstSize(unsigned a) {
return __builtin_clz(~a);
}
If you cannot access __builtin_*(), then you can implement the leading zero counting function as in Hacker's Delight:
int nlz4(unsigned x) {
int y, m, n;
y = -(x >> 16); // If left half of x is 0,
m = (y >> 16) & 16; // set n = 16. If left half
n = 16 - m; // is nonzero, set n = 0 and
x = x >> m; // shift x right 16.
// Now x is of the form 0000xxxx.
y = x - 0x100; // If positions 8-15 are 0,
m = (y >> 16) & 8; // add 8 to n and shift x left 8.
n = n + m;
x = x << m;
y = x - 0x1000; // If positions 12-15 are 0,
m = (y >> 16) & 4; // add 4 to n and shift x left 4.
n = n + m;
x = x << m;
y = x - 0x4000; // If positions 14-15 are 0,
m = (y >> 16) & 2; // add 2 to n and shift x left 2.
n = n + m;
x = x << m;
y = x >> 14; // Set y = 0, 1, 2, or 3.
m = y & ~(y >> 1); // Set m = 0, 1, 2, or 2 resp.
return n + 2 - m;
}
int BurstSize(unsigned a) {
return nlz4(~a);
}
Easiest method: invert the number, then find the most significant bit set. The rest you can do yourself (I am 99% sure this is a homework question, so I am giving a hint only. If you really need more help, ask in the comments and I will expand further).
As for finding the most significant bit set, look at https://stackoverflow.com/a/21413883/1967396
for a fairly efficient method.
update Now for a complete method that finds the most significant bit set (after inverting), and then uses a clever lookup table to convert to actual byte (with a modulo 37 trick that didn't come from me... I found it at http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightModLookup but made a small change so it works for 32 bits set). I include code to test patterns from 0 to 32 bits - seems to work.
#include <stdio.h>
int burstSize(int n) {
// return number of consecutive bits set
unsigned int m, r;
m = ~n;
m = m | m >> 1;
m = m | m >> 2;
m = m | m >> 4;
m = m | m >> 8;
m = m | m >> 16;
m = ((m ^ (m >> 1)) | 0x80000000) & m;
static const int Mod37BitPosition[] = // map a bit value mod 37 to its position
{
-1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4,
7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5,
20, 8, 19, 18
};
r = Mod37BitPosition[m % 37]; // <<<< not sure if this is allowed in your assignment...
return 31 - r; // <<< you could rewrite the LUT so you don't need an operation here. I was lazy.
}
int main(void) {
printf("%d\n", burstSize(0x00000000));
printf("%d\n", burstSize(0x80000000));
printf("%d\n", burstSize(0xC0000000));
printf("%d\n", burstSize(0xE0000000));
printf("%d\n", burstSize(0xF0000000));
printf("%d\n", burstSize(0xF8000000));
printf("%d\n", burstSize(0xFC000000));
printf("%d\n", burstSize(0xFE000000));
printf("%d\n", burstSize(0xFF000000));
printf("%d\n", burstSize(0xFF800000));
printf("%d\n", burstSize(0xFFC00000));
printf("%d\n", burstSize(0xFFE00000));
printf("%d\n", burstSize(0xFFF00000));
printf("%d\n", burstSize(0xFFF80000));
printf("%d\n", burstSize(0xFFFC0000));
printf("%d\n", burstSize(0xFFFE0000));
printf("%d\n", burstSize(0xFFFF0000));
printf("%d\n", burstSize(0xFFFFF800));
printf("%d\n", burstSize(0xFFFFFC00));
printf("%d\n", burstSize(0xFFFFFE00));
printf("%d\n", burstSize(0xFFFFFF00));
printf("%d\n", burstSize(0xFFFFFFF8));
printf("%d\n", burstSize(0xFFFFFFFC));
printf("%d\n", burstSize(0xFFFFFFFE));
printf("%d\n", burstSize(0xFFFFFFFF));
}
TRY THIS:
unsigned int A=0XFFF0; //your own number
unsigned int B0=(1 & A)/1;
unsigned int B1=(2 & A)/2;
unsigned int B2=(4 & A)/4;
unsigned int B3=(8 & A)/8;
unsigned int B4=(16 & A)/16;
unsigned int B5=(32 & A)/32;
unsigned int B6=(64 & A)/64;
unsigned int B7=(128 & A)/128;
unsigned int B8=(256 & A)/256;
unsigned int B9=(512 & A)/512;
unsigned int B10=(1024 & A)/1024;
unsigned int B11=(2048 & A)/2048;
unsigned int B12=(4096 & A)/4096;
unsigned int B13=(8192 & A)/8192;
unsigned int B14=(16384 & A)/16384;
unsigned int B15=(32768 & A)/32768;
int Result=B15+
B14*(B15)+
B13*(B14*B15)+
B12*(B13*B14*B15)+
B11*(B12*B13*B14*B15)+
B10*(B11*B12*B13*B14*B15)+
B9*(B10*B11*B12*B13*B14*B15)+
B8*(B9*B10*B11*B12*B13*B14*B15)+
B7*(B8*B9*B10*B11*B12*B13*B14*B15)+
B6*(B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B5*(B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B4*(B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B3*(B4*B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B2*(B3*B4*B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B1*(B2*B3*B4*B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B0*(B1*B2*B3*B4*B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15);
The following answer reverses the number to do the operation, it doesn't use the % operator, it uses one - sign though:
#include <iostream>
int burstSize(int n) {
// Reverse the bits
n = (n & 0x55555555) << 1 | (n & 0xAAAAAAAA) >> 1;
n = (n & 0x33333333) << 2 | (n & 0xCCCCCCCC) >> 2;
n = (n & 0x0F0F0F0F) << 4 | (n & 0xF0F0F0F0) >> 4;
n = (n & 0x00FF00FF) << 8 | (n & 0xFF00FF00) >> 8;
n = (n & 0x0000FFFF) << 16 | (n & 0xFFFF0000) >> 16;
// rightmost 0-bit, produces 0 if none (e.g., 10100111 -> 00001000)
int r = ~n & (n + 1);
// r - 1 will give us a mask of the consequtive 1s to isolate (e.g., 0100 -> 0011)
n = (r - 1) & n;
// Count the bits
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0F0F0F0F) + ((n >> 4) & 0x0F0F0F0F);
n = (n & 0x00FF00FF) + ((n >> 8) & 0x00FF00FF);
n = (n & 0x0000FFFF) + ((n >>16) & 0x0000FFFF);
// Return the bit count
return n;
}
int main() {
std::cout << burstSize(0x00000000) << std::endl; // 0
std::cout << burstSize(0x00010F00) << std::endl; // 0
std::cout << burstSize(0x80010F00) << std::endl; // 1
std::cout << burstSize(0xF0010F00) << std::endl; // 4
std::cout << burstSize(0xFFFFFFFE) << std::endl; // 31
std::cout << burstSize(0xFFFFFFFF) << std::endl; // 32
return 0;
}

Bit Counting in C similar to bit twiddling hack

I need to make a routine that counts bits in a word that does not involve loops (only bit operations), and does not use large constants.
int x = 0xFFFFFFFF;
x += (~((x >> 1) & 0x55555555)+1);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0F0F0F0F);
x += (x >> 8);
x += (x >> 16);
return(x & 0x0000003F);
This I found on bit twiddling hacks, but the largest constant I can use is 0xFF... Not sure how to do this otherwise.
Thanks folks.
You can for example use a constant array COUNTS[16] which is the number of set bits in the binary representation of numbers from 0 to 15. Then:
static inline int byte_count (int x) {
static const int COUNTS[16] = { 0, 1, 1, 2, 1, /* fill in the rest manually */ };
return COUNTS[x & 15] + COUNTS[x >> 4];
}
int count(int x) {
return byte_count(x >> 24) + byte_count((x >> 16) & 255) + byte_count((x >> 8) & 255) + byte_count(x & 255);
}
No loops and no constants larger than 255.
Using your algorithm:
int x = 0xFF;
x |= (x << 8); // x = 0xFFFF
x |= (x << 16); // x = 0xFFFFFFFF
and then the rest of the code - provided it works.
Recursive solution:
int foo ( int x )
{
if ( x == 0 )
return 0;
return (x & 1) + foo ( x/2 );
}
your question is already answered here
int NumberOfSetBits(int i)
{
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}

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;
}

Resources