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;
}
Related
i would like to read a 32-bits number from binary file in C. The problem is that the order of bits is reversed. For an example 3 digits number 110 would stand for 3, not for 6. At the beginning we have the least significant bit (2^0), then 2^1 and so on. Is there any simple way to do this in C, or do i have to write all the logic by myself (read the first bit, multiply it by 2^0, add to the sum, repeat to the end)?
you have many possible ways:
Portable:
(not my algorithm)
uint32_t rev(uint32_t x)
{
x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
return((x >> 16) | (x << 16));
}
or
uint32_t bit_reverse_4bytes(uint32_t x)
{
x = ((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4);
x = ((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2);
return ((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1);
}
Naive
uint32_t naiverevese(uint32_t x)
{
uint32_t result = 0;
for(int i = 0; i < 32; i++)
{
result |= x & 1;
result <<=1;
x >>= 1;
}
return result;
}
or lookup table.
Not portable but the most efficient:
Many processors have a special instructions for it for example:
ARM - rbit and the intrinsic unsigned int __rbit(unsigned int val)
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
For homework, using C, I'm supposed to make a program that finds the log base 2 of a number greater than 0 using only the operators ! ~ & ^ | + << >>. I know that I'm supposed to shift right a number of times, but I don't know how to keep track of the number of times without having any loops or ifs. I've been stuck on this question for days, so any help is appreciated.
int ilog2(int x) {
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
}
This is what I have so far. I pass the most significant bit to the end.
Assumes a 32-bit unsigned int :
unsigned int ulog2 (unsigned int u)
{
unsigned int s, t;
t = (u > 0xffff) << 4; u >>= t;
s = (u > 0xff ) << 3; u >>= s, t |= s;
s = (u > 0xf ) << 2; u >>= s, t |= s;
s = (u > 0x3 ) << 1; u >>= s, t |= s;
return (t | (u >> 1));
}
Since I assumed >, I thought I'd find a way to get rid of it.
(u > 0xffff) is equivalent to: ((u >> 16) != 0). If subtract borrows:
((u >> 16) - 1) will set the msb, iff (u <= 0xffff). Replace -1 with +(~0) (allowed).
So the condition: (u > 0xffff) is replaced with: (~((u >> 16) + ~0U)) >> 31
unsigned int ulog2 (unsigned int u)
{
unsigned int r = 0, t;
t = ((~((u >> 16) + ~0U)) >> 27) & 0x10;
r |= t, u >>= t;
t = ((~((u >> 8) + ~0U)) >> 28) & 0x8;
r |= t, u >>= t;
t = ((~((u >> 4) + ~0U)) >> 29) & 0x4;
r |= t, u >>= t;
t = ((~((u >> 2) + ~0U)) >> 30) & 0x2;
r |= t, u >>= t;
return (r | (u >> 1));
}
This gets the floor of logbase2 of a number.
int ilog2(int x) {
int i, j, k, l, m;
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
// i = 0x55555555
i = 0x55 | (0x55 << 8);
i = i | (i << 16);
// j = 0x33333333
j = 0x33 | (0x33 << 8);
j = j | (j << 16);
// k = 0x0f0f0f0f
k = 0x0f | (0x0f << 8);
k = k | (k << 16);
// l = 0x00ff00ff
l = 0xff | (0xff << 16);
// m = 0x0000ffff
m = 0xff | (0xff << 8);
x = (x & i) + ((x >> 1) & i);
x = (x & j) + ((x >> 2) & j);
x = (x & k) + ((x >> 4) & k);
x = (x & l) + ((x >> 8) & l);
x = (x & m) + ((x >> 16) & m);
x = x + ~0;
return x;
}
Your result is simply the rank of the highest non-null bit.
int log2_floor (int x)
{
int res = -1;
while (x) { res++ ; x = x >> 1; }
return res;
}
One possible solution is to take this method:
It is based on the additivity of logarithms:
log2(2nx) = log2(x) + n
Let x0 be a number of 2n bits (for instance, n=16 for 32 bits).
if x0 > 2n, we can define x1 so that
x0 = 2nx1
and we can say that
E(log2(x0)) = n + E(log2(x1))
We can compute
x1
with a binary shift:
x1 = x0 >> n
Otherwise we can simply set X1 = X0
We are now facing the same problem with the remaining upper or lower half of x0
By splitting x in half at each step, we can eventually compute E(log2(x)):
int log2_floor (unsigned x)
{
#define MSB_HIGHER_THAN(n) (x &(~((1<<n)-1)))
int res = 0;
if MSB_HIGHER_THAN(16) {res+= 16; $x >>= 16;}
if MSB_HIGHER_THAN( 8) {res+= 8; $x >>= 8;}
if MSB_HIGHER_THAN( 4) {res+= 4; $x >>= 4;}
if MSB_HIGHER_THAN( 2) {res+= 2; $x >>= 2;}
if MSB_HIGHER_THAN( 1) {res+= 1;}
return res;
}
Since your sadistic teacher said you can't use loops, we can hack our way around by computing a value that will be n in case of positive test and 0 otherwise, thus having no effect on addition or shift:
#define N_IF_MSB_HIGHER_THAN_N_OR_ELSE_0(n) (((-(x>>n))>>n)&n)
If the - operator is also forbidden by your psychopatic teacher (which is stupid since processors are able to handle 2's complements just as well as bitwise operations), you can use -x = ~x+1 in the above formula
#define N_IF_MSB_HIGHER_THAN_N_OR_ELSE_0_WITH_NO_MINUS(n) (((~(x>>n)+1)>>n)&n)
that we will shorten to NIMHTNOE0WNM for readability.
Also we will use | instead of + since we know they will be no carry.
Here the example is for 32 bits integers, but you could make it work on 64, 128, 256, 512 or 1024 bits integers if you managed to find a language that supports that big an integer value.
int log2_floor (unsigned x)
{
#define NIMHTNOE0WNM(n) (((~(x>>n)+1)>>n)&n)
int res, n;
n = NIMHTNOE0WNM(16); res = n; x >>= n;
n = NIMHTNOE0WNM( 8); res |= n; x >>= n;
n = NIMHTNOE0WNM( 4); res |= n; x >>= n;
n = NIMHTNOE0WNM( 2); res |= n; x >>= n;
n = NIMHTNOE0WNM( 1); res |= n;
return res;
}
Ah, but maybe you were forbidden to use #define too?
In that case, I cannot do much more for you, except advise you to flog your teacher to death with an old edition of the K&R.
This leads to useless, obfuscated code that gives off a strong smell of unwashed 70's hackers.
Most if not all processors implement specific "count leading zeroes" instructions (for instance, clz on ARM, bsr on x86 or cntlz on PowerPC) that can do the trick without all this fuss .
If you're allowed to use & then can you use &&? With that you can do conditionals without the need of if
if (cond)
doSomething();
can be done with
cond && doSomething();
Otherwise if you want to assign value conditionally like value = cond ? a : b; then you may do it with &
mask = -(cond != 0); // assuming int is a 2's complement 32-bit type
// or mask = (cond != 0) << 31) >> 31;
value = (mask & a) | (~mask & b);
There are many other ways in the bithacks page:
int v; // 32-bit integer to find the log base 2 of
int r; // result of log_2(v) goes here
union { unsigned int u[2]; double d; } t; // temp
t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] = 0x43300000;
t.u[__FLOAT_WORD_ORDER!=LITTLE_ENDIAN] = v;
t.d -= 4503599627370496.0;
r = (t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] >> 20) - 0x3FF;
or
unsigned int v; // 32-bit value to find the log2 of
register unsigned int r; // result of log2(v) will go here
register unsigned int shift;
r = (v > 0xFFFF) << 4; v >>= r;
shift = (v > 0xFF ) << 3; v >>= shift; r |= shift;
shift = (v > 0xF ) << 2; v >>= shift; r |= shift;
shift = (v > 0x3 ) << 1; v >>= shift; r |= shift;
r |= (v >> 1);
another way
uint32_t v; // find the log base 2 of 32-bit v
int r; // result goes here
static const int MultiplyDeBruijnBitPosition[32] =
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
The question is equal to "find the highest bit of 1 of the binary number"
STEP 1: set the left of 1 all to 1
like 0x07000000 to 0x07ffffff
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16); // number of ops = 10
STEP 2: returns count of number of 1's in word and minus 1
Reference: Hamming weight
// use bitCount
int m1 = 0x55; // 01010101...
m1 = (m1 << 8) + 0x55;
m1 = (m1 << 8) + 0x55;
m1 = (m1 << 8) + 0x55;
int m2 = 0x33; // 00110011...
m2 = (m2 << 8) + 0x33;
m2 = (m2 << 8) + 0x33;
m2 = (m2 << 8) + 0x33;
int m3 = 0x0f; // 00001111...
m3 = (m3 << 8) + 0x0f;
m3 = (m3 << 8) + 0x0f;
m3 = (m3 << 8) + 0x0f;
x = x + (~((x>>1) & m1) + 1); // x - ((x>>1) & m1)
x = (x & m2) + ((x >> 2) & m2);
x = (x + (x >> 4)) & m3;
// x = (x & m3) + ((x >> 4) & m3);
x += x>>8;
x += x>>16;
int bitCount = x & 0x3f; // max 100,000(2) = 32(10)
// Number of ops: 35 + 10 = 45
return bitCount + ~0;
This is how I do. Thank you~
I also was assigned this problem for homework and I spent a significant amount of time thinking about it so I thought I'd share what I came up with. This works with integers on a 32 bit machine. !!x returns if x is zero or one.
int ilog2(int x) {
int byte_count = 0;
int y = 0;
//Shift right 8
y = x>>0x8;
byte_count += ((!!y)<<3);
//Shift right 16
y = x>>0x10;
byte_count += ((!!y)<<3);
//Shift right 24 and mask to adjust for arithmetic shift
y = (x>>0x18)&0xff;
byte_count += ((!!y)<<3);
x = (x>>byte_count) & 0xff;
x = x>>1;
byte_count += !!x;
x = x>>1;
byte_count += !!x;
x = x>>1;
byte_count += !!x;
x = x>>1;
byte_count += !!x;
x = x>>1;
byte_count += !!x;
x = x>>1;
byte_count += !!x;
x = x>>1;
byte_count += !!x;
x = x>>1; //8
byte_count += !!x;
return byte_count;
}
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;
}
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;
}