This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Best algorithm to count the number of set bits in a 32-bit integer?
Given a 32-bit integer N,Devise an algorithm to find the number of zeros in the binary bit representation of N.
The simplest algorithm I can think of is to check the binary representation for Zeros,in C something like this:
int num_of_zero(int num)
{
if(0 == num) return 1; /*For the input 0 it should output 1 */
int Count = 0;
while(num>0){
if(0 == (num&1)) Count++;
num >>= 1;
}
return Count;
}
I was wandering if there is some algorithm to compute at constant time.
For input 0 it should return 1 not 32.
For 5 the output should be 1.As binary representation is 101.
For 7 the output should be 0.
Precisely,I am looking for a better algorithm to compute number of (non-leading) zeros in the binary interpretation of an 32 bit integer.Hope the problem is clear now.
Edit: As pointed Alex Martelli,delroth I am modifying my code to made it more readable & using iteration this time.
The simple way to do this is to iterate over each bit of the binary representation of the number, test the value of each bit, and count up how many of them are zero. A loop would be much clearer than recursion for this.
There are many more optimized methods for doing this, though. You can find some of the better ones in answers to this question, "Best algorithm to count the number of set bits in a 32-bit integer" (obviously, the number of zero bits is the number of set bits subtracted from the total number of bits).
There's a great resource online called Bit Twiddling Hacks that contains all sorts of great little C tricks. You may be particularly interested in the Counting bits set section.
Quick and dumb way -- there are more exotic implementations in the duplicate question, but I have used something similar to this without much ill effect in the past.
We use a table of nibbles here to reduce the number of times the loop is run -- if you're doing a boatload of these computations, it might be more efficient to build a much bigger array, say, at the byte level, cutting the loop runs in half.
/* How many bits are set in every possible nibble. */
static size_t BIT_TABLE[] = {
0, 1, 1, 2, /* 0, 1, 2, 3 */
1, 2, 2, 3, /* 4, 5, 6, 7 */
1, 2, 2, 3, /* 8, 9, A, B */
2, 3, 3, 4 /* C, D, E, F */
};
size_t num_of_bits(int num) {
/* Little reworking could probably shrink the stack space in use here. */
size_t ret = 0, i;
register int work = num;
/* Iterate every nibble, rotating the integer in place. */
for(i = 0; i < (sizeof(num) * 2); i++) {
/* Pointer math to get a member of the static array. */
ret += *(BIT_TABLE + (work & 0xF));
work >>= 4;
}
return ret;
}
Recursion is definitely overkill -- and besides, your code's quite buggy (it will not count any of the leading zeros of num!!!). A simple iteration, such as:
int num_of_zero(int num) {
unsigned int unum = (unsigned int)num;
int count;
int i;
for(i = 0; i < 32; ++i) {
if(!(unum & 1)) ++count;
unum >>= 1;
}
return count;
}
is correct and faster (can be coded more concisely, but I think this is the clearest expression).
If you have to do this computation many times, consider precomputing an array of (say) 256 "counts of zeros" (each value giving the count for its index, 0 to 255 included, as an 8-bit number). Then you can loop just 4 times (masking and shifting 8 bits at a time), and easily unroll the loop -- if your compiler's not smart enough to do it on your behalf;-).
I'm guessing that this is a homework question. No problem! Here's the fastest possible solution (after a long startup cost):
Make an array of byte that is 232 long. Precompute the value of the number of zeros in the binary representation for each possible int value to fill in that array. From then on, you'll have an array that will give you the number of zeros per value.
Yes, that solution is silly -- it's a lot of work for little gain -- but combine it with one other idea:
What happens if you just precompute the values that are 8 bits long? Would you be able to write code that, though not quite as fast, would still return the number of 0-bits in a int?
What happens if you just precompute the values that are 4 bits long? 2 bits long? 1 bit long?
I hope this gives you ideas for a better algorthm...
It is not really an answer to your main question, but you should rewrite your recursive function like this :
int num_of_zero(int num)
{
int left_part_zeros;
if (num == 0)
return 0;
left_part_zeros = num_of_zero(num >> 1);
if ((num & 1) == 0)
return left_part_zeros + 1;
else
return left_part_zeros;
}
Your implementation have a lot of problems, beside being completely unreadable.
The easiest way I found was to base it on something that counts the ones then simply subtract that from 32 (assuming that you're sure the int size is 32 bits).
int numberOfOnes (int num) {
int count = 0;
unsigned int u = (unsigned int)num;
while (u != 0) {
if ((u&1) == 1)
count++;
u >>= 1;
}
return count;
}
int numberOfZeros (int num) {
return 32 - numberOfOnes (num);
}
This actually gives you both variants (ones and zeros) - there are faster ways to do it but I wouldn't consider them unless and until you know there's a performance problem. I tend to code for readability first.
You may also want to at least test the possibility that a table lookup could be faster (the prime directive of optimisation is measure, don't guess!
One possibility there could be replacing the numberOfOnes function with something that operates a nybble at a time:
int numberOfOnes (int num) {
static const count[] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
};
int retval = 0;
unsigned int u = (unsigned int)num;
while (u != 0) {
retval += count[u & 0x0f]
u >>= 4;
}
return retval;
}
Related
I dont understand why the interger Value "hash" is getting lower in/after the 3 loop.
I would guess this happen because the uint limitation is 2,147,483,647.
BUT... when i try to go step by step the value is equal to 2146134658?.
I´m not that good in math but it should be lower than the limitation.
#define FNV_PRIME_32 16777619
#define FNV_OFFSET_32 2166136261U
unsigned int hash_function(const char *string, unsigned int size)
{
unsigned int str_len = strlen(string);
if (str_len == 0) exit(0);
unsigned int hash = FNV_OFFSET_32;
for (unsigned int i = 0; i < str_len; i++)
{
hash = hash ^ string[i];
// Multiply by prime number found to work well
hash = hash * FNV_PRIME_32;
if (hash > 765010506)
printf("YO!\n");
else
printf("NOO!\n");
}
return hash % size;
}
If you are wondering this if statement is only for me.
if (hash > 765010506)
printf("YO!\n");
else
printf("NOO!\n");
765010506 is the value for hash after the next run through the loop.
I dont understand why the interger Value "hash" is getting lower in/after the 3 loop.
All unsigned integer arithmetic in C is modular arithmetic. For unsigned int, it is modulo UINT_MAX + 1; for unsigned long, modulo ULONG_MAX + 1, and so on.
(a modulo m means the remainder of a divided by m; in C, a % m if both a and m are unsigned integer types.)
On many current architectures, unsigned int is a 32-bit unsigned integer type, with UINT_MAX == 4294967295.
Let's look at what this means in practice, for multiplication (by 65520, which happens to be an interesting value; 216 - 16):
unsigned int x = 1;
int i;
for (i = 0; i < 10; i++) {
printf("%u\n", x);
x = x * 65520;
}
The output is
1
65520
4292870400
50327552
3221291008
4293918720
16777216
4026531840
0
0
What? How? How come the result ends up zero? That cannot happen!
Sure it can. In fact, you can show mathematically that it happens eventually whenever the multiplier is even, and the modulo is with respect to a power of two (232, here).
Your particular multiplier is odd, however; so, it does not suffer from the above. However, it still wraps around due to the modulo operation. If we retry the same with your multiplier, 16777619, and a bit longer sequence,
unsigned int x = 1;
int i;
for (i = 0; i < 20; i++) {
printf("%u\n", x);
x = x * 16777619;
}
we get
1
16777619
637696617
1055306571
1345077009
1185368003
4233492473
878009595
1566662433
558416115
1485291145
3870355883
3549196337
924097827
3631439385
3600621915
878412353
2903379027
3223152297
390634507
In fact, it turns out that this sequence is 1,073,741,824 iterations long (before it repeats itself), and will never yield 0, 2, 4, 5, 6, 7, 8, 10, 12, 13, 14, or 15, for example -- that is, if it starts from 1. It even takes 380 iterations to get a result smaller than 16,777,619 (16,689,137).
For a hash function, that is okay. Each new nonzero input changes the state, so the sequence is not "locked". But, there is no reason to expect the hash value increases monotonically as the length of the hashed data increases; it is much better to assume it is "roughly random" instead: not really random, as it depends on the input only, but also not obviously regular-looking.
I would guess this happen because the uint limitation is 2,147,483,647.
The maximum value of a 32-bit unsigned integer is roughly 4 billion (232 - 1 = 4,294,967,295). The number you're thinking of is the maximum value of a signed integer (231 - 1).
2,146,134,658 is slightly less than 231 (so it could fit in even an unsigned 32-bit integer), but it's still very close to the limit. Multiplying it by FNV_PRIME_32 -- which is roughly 224 -- will give a result of roughly 255, which will cause overflow.
I'm struggling to adapt to C after programming in Java for some time and I need help. What I'm looking for is a method that takes following input:
Integer n, the one to be converted to binary string (character array).
Integer length, which defines the length of the string (positions from the left not filled with the binary numbers are going to be set to default 0).
//Here's some quick code in Java to get a better understanding of what I'm looking for:
public static String convertToBinary(int length, int n) {
return String.format("%1$" + bit + "s", Integer.toBinaryString(value)).replace(' ', '0');
}
System.out.println(convertToBinary(8,1));
// OUTPUT:
00000001 (not just 1 or 01)
Any hints on what the equivalent of this would be in C? Also, could you provide me with an example of how the resulting binary string should be returned?
(not a duplicate, since what I'm looking for is '00000001', not simply '1')
The C standard library does not contain an equivalent function to Integer.toBinaryString(). The good news is, writing such a function won't be too complicated, and if you're in the process of learning C, this problem is fairly ideal for learning how to use the bitwise operators.
You'll want to consult an existing tutorial or manual for all the details, but here are a few examples of the sort of things that would be useful for this or similar tasks. All numbers are unsigned integers in these examples.
n >> m shifts all bits in n right by m steps, and fills in zeros on the left side. So if n = 13 (1101 in binary), n >> 1 would be 6 (i.e. 110), and n >> 2 would be 3 (i.e. 11).
n << m does the same thing, but shifting left. 3 << 2 == 12. This is equivalent to multiplying n by 2 to the power of m. (If it isn't obvious why that is, you'll want to think about how binary numbers are represented for awhile until you understand it clearly; it'll make things easier if you have an intuitive understanding of that property.)
n & m evaluates to a number such that each bit of the result is 1 if and only if it's 1 in both n and m. e.g. 12 & 5 == 4, (1100, 0101, and 0100 being the respective representations of 12, 5, and 4).
So putting those together, n & (1 << i) will be nonzero if and only if bit i is set: 1 obviously only has a single bit set, 1 << i moves it to the appropriate position, and n & (1 << i) checks if that position also has a 1 bit for n. (keeping in mind that the rightmost/least significant bit is bit 0, not bit 1.) So using that, it's a simple matter of checking each bit individually to see if it's 1 or 0, and you have your binary conversion function.
like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
char *convertToBinary(int length, int n) {
unsigned num = (unsigned)n;
int n_bit = CHAR_BIT * sizeof(num);
if(length > n_bit){
fprintf(stderr, "specified length greater than maximum length.\n");
length = n_bit;//or expand size?
}
char *bin = malloc(n_bit + 1);//static char bin[CHAR_BIT * sizeof(num)+1]; If you change, memmove(-->return p;), free is not necessary.
memset(bin, '0', n_bit);
bin[n_bit] = 0;
char *p = bin + n_bit;
do {
*--p = "01"[num & 1];
num >>= 1;
}while(num);
int bits = bin + n_bit - p;
if(bits < length){
p -= length - bits;
return memmove(bin, p, length + 1);
} else if(bits > length){
fprintf(stderr, "Specified length is not enough.(%s but length is %d)\n", p, length);
return memmove(bin, p, bits+1);//or cut off
/*
free(bin);
return ""; or return NULL;
*/
}// else if(bits == length)
return bin;
}
int main(void){
char *sbin = convertToBinary(8, 1);
puts(sbin);
free(sbin);
return 0;
}
I was charged with the task of writing a method that "returns the word with all even-numbered bits set to 1." Being completely new to C this seems really confusing and unclear. I don't understand how I can change the bits of a number with C. That seems like a very low level instruction, and I don't even know how I would do that in Java (my first language)! Can someone please help me! This is the method signature.
int evenBits(void){
return 0;
}
Any instruction on how to do this or even guidance on how to begin doing this would be greatly appreciated. Thank you so much!
Break it down into two problems.
(1) Given a variable, how do I set particular bits?
Hint: use a bitwise operator.
(2) How do I find out the representation of "all even-numbered bits" so I can use a bitwise operator to set them?
Hint: Use math. ;-) You could make a table (or find one) such as:
Decimal | Binary
--------+-------
0 | 0
1 | 1
2 | 10
3 | 11
... | ...
Once you know what operation to use to set particular bits, and you know a decimal (or hexadecimal) integer literal to use that with in C, you've solved the problem.
You must give a precise definition of all even numbered bits. Bits are numbered in different ways on different architectures. Hardware people like to number them from 1 to 32 from the least significant to the most significant bit, or sometimes the other way, from the most significant to the least significant bit... while software guys like to number bits by increasing order starting at 0 because bit 0 represents the number 20, ie: 1.
With this latter numbering system, the bit pattern would be 0101...0101, thus a value in hex 0x555...555. If you number bits starting at 1 for the least significant bit, the pattern would be 1010...1010, in hex 0xAAA...AAA. But this representation actually encodes a negative value on current architectures.
I shall assume for the rest of this answer that even numbered bits are those representing even powers of 2: 1 (20), 4 (22), 16 (24)...
The short answer for this problem is:
int evenBits(void) {
return 0x55555555;
}
But what if int has 64 bits?
int evenBits(void) {
return 0x5555555555555555;
}
Would handle 64 bit int but would have implementation defined behavior on systems where int is smaller.
Using macros from <limits.h>, you could mask off the extra bits to handle 16, 32 and 64 bit ints:
#include <limits.h>
int evenBits(void) {
return 0x5555555555555555 & INT_MAX;
}
But this code still makes some assumptions:
int has at most 64 bits.
int has an even number of bits.
INT_MAX is a power of 2 minus 1.
These assumptions are valid for most current systems, but the C Standard allows for implementations where one or more are invalid.
So basically every other bit has to be set to one? This is why we have bitwise operations in C. Imagine a regular bitarray. What you want is the right most even bit and set it to 1(this is the number 2). Then we just use the OR operator (|) to modify our existing number. After doing that. we bitshift the number 2 places to the left (<< 2), this modifies the bit array to 1000 compared to the previous 0010. Then we do the same again and use the or operator. The code below describes it better.
#include <stdio.h>
unsigned char SetAllEvenBitsToOne(unsigned char x);
int IsAllEvenBitsOne(unsigned char x);
int main()
{
unsigned char x = 0; //char is one byte data type ie. 8 bits.
x = SetAllEvenBitsToOne(x);
int check = IsAllEvenBitsOne(x);
if(check==1)
{
printf("shit works");
}
return 0;
}
unsigned char SetAllEvenBitsToOne(unsigned char x)
{
int i=0;
unsigned char y = 2;
for(i=0; i < sizeof(char)*8/2; i++)
{
x = x | y;
y = y << 2;
}
return x;
}
int IsAllEvenBitsOne(unsigned char x)
{
unsigned char y;
for(int i=0; i<(sizeof(char)*8/2); i++)
{
y = x >> 7;
if(y > 0)
{
printf("x before: %d\t", x);
x = x << 2;
printf("x after: %d\n", x);
continue;
}
else
{
printf("Not all even bits are 1\n");
return 0;
}
}
printf("All even bits are 1\n");
return 1;
}
Here is a link to Bitwise Operations in C
I have a bit array prime[]of unsigned int. I wish to implement a Sieve of Eratosthenes using this array, by having each bit represent a number n. That is, given n, the array element that holds the bit that corresponds to n would be prime[n/32] and the specific bit would be in position n%32.
My testBitIs0(int n) function returns 1 when the number is prime (if its bit == 0), otherwise 0:
return ( (prime[n/32] & (1 << (n%32) )) != 0);
My setBit(int n) function simply sets the bit to 1 at the corresponding position:
int i = n/32;
int pos = n%32;
unsigned int flag = 1;
flag = flag << pos;
prime[i] = prime[i] | flag;
The issue that I'm having is that when I call setBit with multiples of a prime number, I don't think it sets the bit correctly. When I call setBit with multiples of a prime number (such as 4, 6, 8, etc. for the number 2) the next time I run this line:
if(testBitIs0(i)) { ... }
With i = 4/6/8/etc it will still return 1 when it should return 0.
Can someone please check my code to make sure I am implementing this correctly? Thanks.
This looks like it does what you're after. There's a bit array and some bit twiddling functions too.
http://bcu.copsewood.net/dsalg/bitwise/bitwise.html
My Need:
For any non - negative unsigned long a,
Input a = 5; Ans should be 3
Input a = 12; Ans should be 4
Input a = 1; Ans should be 1
Input a=0 Ans should be 0
i.e to Find the most significant 1 position from the left.
What I have tried:
int count = 0;
if( a!=0 )
do{
count++;
}while( a >>= 1 );
Problem
Takes more time because of while loop and shifting.
Proposed method
If I know how the 4 bytes is stored in memory, (using char*) I will take out the byte, which contains the most significant 1, thus in worst case maximum 8 shifting will suffice to find the answer.
Don't do that. Your method won't work if the most significant byte doesn't contain the bit you're looking for (i. e. if your number is less than 2 ^ (3 * CHAR_BIT)). Why don't you just start from the other end?
unsigned find_msb(unsigned long long n)
{
int bits_max = sizeof(n) * CHAR_BIT - 1;
int i;
for (i = bits_max; i >= 0; i--) {
if ((n >> i) & 1) return i + 1;
}
return 0;
}
I think you are way to worried about efficiency. Worst case is O(n) and frankly it's never going to get any better. Even in an embedded system on a slow processor there's no real need to try and speed up H2CO3's algorithm.
Get it working, then worry about efficiency.