Count number of bits in an unsigned integer - c

I want to write a function named bitCount() in the file: bitcount.c that returns the number of bits in the binary representation of its unsigned integer argument.
Here is what I have so far:
#include <stdio.h>
int bitCount (unsigned int n);
int main () {
printf ("# 1-bits in base 2 representation of %u = %d, should be 0\n",
0, bitCount (0));
printf ("# 1-bits in base 2 representation of %u = %d, should be 1\n",
1, bitCount (1));
printf ("# 1-bits in base 2 representation of %u = %d, should be 16\n",
2863311530u, bitCount (2863311530u));
printf ("# 1-bits in base 2 representation of %u = %d, should be 1\n",
536870912, bitCount (536870912));
printf ("# 1-bits in base 2 representation of %u = %d, should be 32\n",
4294967295u, bitCount (4294967295u));
return 0;
}
int bitCount (unsigned int n) {
/* your code here */
}
Okay, when I just run this I get:
# 1-bits in base 2 representation of 0 = 1, should be 0
# 1-bits in base 2 representation of 1 = 56, should be 1
# 1-bits in base 2 representation of 2863311530 = 57, should be 16
# 1-bits in base 2 representation of 536870912 = 67, should be 1
# 1-bits in base 2 representation of 4294967295 = 65, should be 32
RUN SUCCESSFUL (total time: 14ms)
It doesn't return the correct numbers of bits.
What's the best way to return the number of bits in the binary representation of its unsigned integer argument in C?

Here's a solution that doesn't need to iterate. It takes advantage of the fact that adding bits in binary is completely independent of the position of the bit and the sum is never more than 2 bits. 00+00=00, 00+01=01, 01+00=01, 01+01=10. The first addition adds 16 different 1-bit values simultaneously, the second adds 8 2-bit values, and each one after does half as many until there's only one value left.
int bitCount(unsigned int n)
{
n = ((0xaaaaaaaa & n) >> 1) + (0x55555555 & n);
n = ((0xcccccccc & n) >> 2) + (0x33333333 & n);
n = ((0xf0f0f0f0 & n) >> 4) + (0x0f0f0f0f & n);
n = ((0xff00ff00 & n) >> 8) + (0x00ff00ff & n);
n = ((0xffff0000 & n) >> 16) + (0x0000ffff & n);
return n;
}
This is hard-coded to 32 bit integers, if yours are a different size it will need adjusting.

int bitCount(unsigned int n) {
int counter = 0;
while(n) {
counter += n % 2;
n >>= 1;
}
return counter;
}

Turns out there are some pretty sophisticated ways to compute this as answered here.
The following impl (I learned way back) simply loops knocking off the least significant bit on each iteration.
int bitCount(unsigned int n) {
int counter = 0;
while(n) {
counter ++;
n &= (n - 1);
}
return counter;
}

Related

How to see if the two's complement of a number x can be represented in n number of bits

fitsBits - return 1 if x can be represented as an
n-bit, two's complement integer.
1 <= n <= 32
Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
Legal ops: ! ~ & ^ | + << >>
My code is the following:
int fitsBits(int x, int n) {
int twos = ~x + 1; //two's complement
int ans;
ans = (twos >> (n);
ans = !ans;
return ans;
}
Working it on paper, it seems to work correctly but it fails when actually tested and I'm not sure why.
I'm assuming you are working on a 2s complement machine (vice sign-magnitude or some other kind of arithmetic) and need to avoid loops and conditionals as well. This is clearly some kind of puzzle, so let's not worry about portability and assume 32-bit ints.
If the value is positive, all bits from n-1 through the highest order bit of the int must be zeros. If the value is negative, the same bits must be ones. So one approach is to check those bits for the correct value.
This is equivalent to checking whether x >> (~0+n) is all zeros if x is positive and all ones otherwise. It "shifts out" the bits that are free to have any value.
We can also construct a mask that's all zeros if x is positive, else ones, with x >> 31.
Finally, we can check equality of any ints a and b using !(a ^ b).
Putting all this together, you'd get:
int fitBits(int val, int nbits) {
return !((val >> 31) ^ (val >> (~0 + nbits)));
}
You want the log base 2.
#include <stdio.h>
int fitsBits(unsigned int v, unsigned int n) {
unsigned int r = 0; // lg(v)
while (v >>= 1) {
r++;
}
if(r >= n) return 1;
return 0;
}
int main () {
printf(" 5,3 => %d\n", fitsBits( 5,3));
printf(" -4,3 => %d\n", fitsBits(-4,3));
}
output:
5,3 => 0
-4,3 => 1

how can i convert hexadecimal number to binary using bit-mask

int main()
{
double hexa_number;
double bitmask = 0x80;
double i;
printf("Enter 8 bit number in hexadecimal form: ");
scanf("%lf",& hexa_number);
for( i = 0; i <= 8; i++)
{
if(hexa_number&(bitmask >> i))
printf("1");
else
printf("0");
}
return 0;
}
plus Displaying the binary representation of this number,
along with a count of the number of 0’s and 1’s in the binary number.
i found other ways to convert it but not with bitmask
The problem could be that you are using a double for your bitmask. I don't think >> makes much sense for doubles especially as they are composed of a sign bit, mantissa and 2^ exponent.
For example, 8 >> 1 is 4. That is a nice consistent operation, same as division by 2.
If we imagine an unsigned two byte float for simplicity and imagine that the first byte represents the mantissa and the second the exponent (both unsigned), then 7 * 2^4 (=112) could be represented as 0b00000111 00000100. If you shift that 1 to the right, >> 1, you will get 0b00000011 10000010, which by our convention is now 3 * 2^130. This is definitely not the division by 2 you would get by shifting an integer right by 1.
My compiler gives "error: invalid operands to binary >> (have double and unsigned)" if I try bitwise shifting a floating point number.
So basically you could try the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int hexa_number = 0;
unsigned num_bits = sizeof(int)*8;
unsigned bitmask = 1 << (num_bits - 1);
printf("Enter a number in hexadecimal form: ");
scanf("%i", &hexa_number);
unsigned k = 0;
unsigned num_ones = 0;
unsigned num_zeros = 0;
for(k = 0; k != num_bits; k ++)
{
if(hexa_number & (bitmask >> k))
{
printf("1");
num_ones ++;
}
else
{
printf("0");
num_zeros++;
}
}
printf("\nNumber of ones is %i\nNumber of zeros is %i", num_ones, num_zeros);
return 0;
}

How to represent binary data in 8 bits in C

#include<stdio.h>
int main()
{
long int decimalNumber,remainder,quotient;
int binaryNumber[100],i=1,j;
printf("Enter any decimal number: ");
scanf("%ld",&decimalNumber);
quotient = decimalNumber;
while(quotient!=0)
{
binaryNumber[i++]= quotient % 2;
quotient = quotient / 2;
}
printf("Equivalent binary value of decimal number %d: ",decimalNumber);
for(j = i -1 ;j> 0;j--)
printf("%d",binaryNumber[j]);
return 0;
}
I want the output in 8 bit binary form, but the result as shown below, is there any operator in C which can convert 7 bit data to its equivalent 8 bit data? thank you
Sample output:
Enter any decimal number: 50
Equivalent binary value of decimal number 50: 110010
Required output is 00110010 which is 8 bit, how to append a zero in MSB position?
A very convenient way it so have a function return a binary representation in the form of a string. This allows the binary representation to be used within a normal printf format string rather than having the bits spit out at the current cursor position. To specify the exact number of digits, you must pad the binary string to the required number of places (e.g. 8, 16, 32...). The following makes use of a static variable to allow the return of the buffer, but the same can easily be implemented by allocating space for the buffer with dynamically. The preprocessor checks are not required as you can simply hardwire the length of the buffer to 64 + 1, but for the sake of completeness a check for x86/x86_64 is included and BITS_PER_LONG is set accordingly.
#include <stdio.h>
#if defined(__LP64__) || defined(_LP64)
# define BUILD_64 1
#endif
#ifdef BUILD_64
# define BITS_PER_LONG 64
#else
# define BITS_PER_LONG 32
#endif
char *binstr (unsigned long n, size_t sz);
int main (void) {
printf ("\n 50 (decimal) : %s (binary)\n\n", binstr (50, 8));
return 0;
}
/* returns pointer to binary representation of 'n' zero padded to 'sz'. */
char *binstr (unsigned long n, size_t sz)
{
static char s[BITS_PER_LONG + 1] = {0};
char *p = s + BITS_PER_LONG;
register size_t i;
if (!n) {
*s = '0';
return s;
}
for (i = 0; i < sz; i++)
*(--p) = (n>>i & 1) ? '1' : '0';
return p;
}
Output
$ ./bin/bincnv
50 (decimal) : 00110010 (binary)
Note: you cannot make repeated calls in the same printf statement due to the static buffer. If you allocate dynamically, you can call the function as many times as you like in the same printf statement.
Also, note, if you do not care about padding the binary return to any specific length and just want the binary representation to start with the most significant bit, the following simpler version can be used:
/* simple return of binary string */
char *binstr (unsigned long n)
{
static char s[BITS_PER_LONG + 1] = {0};
char *p = s + BITS_PER_LONG;
if (!n) {
*s = '0';
return s;
}
while (n) {
*(--p) = (n & 1) ? '1' : '0';
n >>= 1;
}
return p;
}
Modify your code as shown below:
quotient = quotient / 2;
}
/* ---- Add the following code ---- */
{
int group_size = 8; /* Or CHAR_BIT */
int padding = group_size - ((i-1) % group_size); /* i was inited with 1 */
if(padding != group_size) {
/* Add padding */
while(padding-- != 0) binaryNumber[i++] = 0;
}
}
/* ------- Modification ends -------- */
printf("Equivalent binary value of decimal number %d: ",decimalNumber);
This code calculates the number of padding bits required to print the number and fills the padding bits with 0.
Live demo here
If you want 7 bit answer, change group_size to 7.
Use this for printing your result:
for(j = 7; j>0; j--)
printf("%d", binaryNumber[j]);
This always prints 8 binary digits.
Edit
The int array binaryNumber must be initialized with zeros to make this work:
for(int i=0; i<8; i++) binaryNumber[i] = 0;

Is this the proper way to count the number of 0s in a binary number?

#include <stdio.h>
int NumberOfSetBits(int);
int main(int argc, char *argv[]) {
int size_of_int = sizeof(int);
int total_bit_size = size_of_int * 8;
// binary representation of 3 is 0000011
// C standard doesn't support binary representation directly
int n = 3;
int count = NumberOfSetBits(n);
printf("Number of set bits is: %d\n", count);
printf("Number of unset bits is: %d", total_bit_size - count);
}
int NumberOfSetBits(int x)
{
int count = 0;
//printf("x is: %d\n", x);
while (x != 0) {
//printf("%d\n", x);
count += (x & 1);
x = x >> 1;
}
return count;
}
Number of set bits is: 2
Number of unset bits is: 30
int size_of_int = sizeof(int);
int total_bit_size = size_of_int * 8;
^ that will get the size of the int on the system and times it by 8 which is the number of bits in each byte
EDITED: Without the use of the ~
/*
Calculate how many set bits and unset bits are in a binary number aka how many 1s and 0s in a binary number
*/
#include <stdio.h>
unsigned int NumberOfSetBits(unsigned int);
unsigned int NumberOfUnSetBits(unsigned int x);
int main() {
// binary representation of 3 is 0000011
// C standard doesn't support binary representation directly
unsigned int n = 3;
printf("Number of set bits is: %u\n", NumberOfSetBits(n));
printf("Number of unset bits is: %u", NumberOfUnSetBits(n));
return 0;
}
unsigned int NumberOfSetBits(unsigned int x) {
// counts the number of 1s
unsigned int count = 0;
while (x != 0) {
count += (x & 1);
// moves to the next bit
x = x >> 1;
}
return count;
}
unsigned int NumberOfUnSetBits(unsigned int x) {
// counts the number of 0s
unsigned int count = 0;
while(x != 0) {
if ((x & 1) == 0) {
count++;
}
// moves to the next bit
x = x >> 1;
}
return count;
}
returns for input 3
Number of set bits is: 2
Number of unset bits is: 0
unset bits is 0? Doesn't seem right?
if I use NumberOfSetBits(~n) it returns 30
You've got a problem on some systems because you right shift a signed integer in your bit-counting function, which may shift 1's into the MSB each time for negative integers.
Use unsigned int (or just unsigned) instead:
int NumberOfSetBits(unsigned x)
{
int count = 0;
//printf("x is: %d\n", x);
while (x != 0) {
//printf("%d\n", x);
count += (x & 1);
x >>= 1;
}
return count;
}
If you fix that part of the problem, you can solve the other with:
int nbits = NumberOfSetBits(~n);
where ~ bitwise inverts the value in n, and hence the 'set bit count' counts the bits that were zeros.
There are also faster algorithms for counting the number of bits set: see Bit Twiddling Hacks.
To solve the NumberOfSetBits(int x) version without assuming 2's complement nor absence of padding bits is a challenge.
#Jonathan Leffler has the right approach: use unsigned. - Just thought I'd try a generic int one.
The x > 0, OP's code work fine
int NumberOfSetBits_Positive(int x) {
int count = 0;
while (x != 0) {
count += (x & 1);
x = x >> 1;
}
return count;
}
Use the following to find the bit width and not count padding bits.
BitWidth = NumberOfSetBits_Positive(INT_MAX) + 1;
With this, the count of 0 or 1 bits is trivial.
int NumberOfClearBits(int x) {
return NumberOfSetBits_Positive(INT_MAX) + 1 - NumberOfSetBits(x);
}
int NumberOfSetBits_Negative(int x) {
return NumberOfSetBits_Positive(INT_MAX) + 1 - NumberOfSetBits_Positive(~x);
}
All that is left is to find the number of bits set when x is 0. +0 is easy, the answer is 0, but -0 (1's compliment or sign magnitude) is BitWidth or 1.
int NumberOfSetBits(int x) {
if (x > 0) return NumberOfSetBits_Positive(x);
if (x < 0) return NumberOfSetBits_Negative(x);
// Code's assumption: Only 1 or 2 forms of 0.
/// There may be more because of padding.
int zero = 0;
// is x has same bit pattern as +0
if (memcmp(&x, &zero, sizeof x) == 0) return 0;
// Assume -0
return NumberOfSetBits_Positive(INT_MAX) + 1 - NumberOfSetBits_Positive(~x);
}
here is a proper way to count the number of zeores in a binary number
#include <stdio.h>
unsigned int binaryCount(unsigned int x)
{
unsigned int nb=0; // will count the number of zeores
if(x==0) //for the case zero we need to return 1
return 1;
while(x!=0)
{
if ((x & 1) == 0) // the condition for getting the most right bit in the number
{
nb++;
}
x=x>>1; // move to the next bit
}
return nb;
}
int main(int argc, char *argv[])
{
int x;
printf("input the number x:");
scanf("%d",&x);
printf("the number of 0 in the binary number of %d is %u \n",x,binaryCount(x));
return 0;
}

unsigned to hex digit

I got a problem that says: Form a character array based on an unsigned int. Array will represent that int in hexadecimal notation. Do this using bitwise operators.
So, my ideas is the following: I create a mask that has 1's for its 4 lowest value bits.
I push the bits of the given int by 4 to the right and use & on that int and mask. I repeat until (int != 0). My question is: when I get individual hex digits (packs of 4 bits), how do I convert them to a char? For example, I get:
x & mask = 1101(2) = 13(10) = D(16)
Is there a function to convert an int to hex representation, or do I have to use brute force with switch statement or whatever else?
I almost forgot, I am doing this in C :)
Here is what I mean:
#include <stdio.h>
#include <stdlib.h>
#define BLOCK 4
int main() {
unsigned int x, y, i, mask;
char a[4];
printf("Enter a positive number: ");
scanf("%u", &x);
for (i = sizeof(usnsigned int), mask = ~(~0 << 4); x; i--, x >>= BLOCK) {
y = x & mask;
a[i] = FICTIVE_NUM_TO_HEX_DIGIT(y);
}
print_array(a);
return EXIT_SUCCESS;
}
You are almost there. The simplest method to convert an integer in the range from 0 to 15 to a hexadecimal digit is to use a lookup table,
char hex_digits[] = "0123456789ABCDEF";
and index into that,
a[i] = hex_digits[y];
in your code.
Remarks:
char a[4];
is probably too small. One hexadecimal digit corresponds to four bits, so with CHAR_BIT == 8, you need up to 2*sizeof(unsigned) chars to represent the number, generally, (CHAR_BIT * sizeof(unsigned int) + 3) / 4. Depending on what print_array does, you may need to 0-terminate a.
for (i = sizeof(usnsigned int), mask = ~(~0 << 4); x; i--, x >>= BLOCK)
initialising i to sizeof(unsigned int) skips the most significant bits, i should be initialised to the last valid index into a (except for possibly the 0-terminator, then the penultimate valid index).
The mask can more simply be defined as mask = 0xF, that has the added benefit of not invoking undefined behaviour, which
mask = ~(~0 << 4)
probably does. 0 is an int, and thus ~0 is one too. On two's complement machines (that is almost everything nowadays), the value is -1, and shifting negative integers left is undefined behaviour.
char buffer[10] = {0};
int h = 17;
sprintf(buffer, "%02X", h);
Try something like this:
char hex_digits[] = "0123456789ABCDEF";
for (i = 0; i < ((sizeof(unsigned int) * CHAR_BIT + 3) / 4); i++) {
digit = (x >> (sizeof(unsigned int) * CHAR_BIT - 4)) & 0x0F;
x = x << 4;
a[i] = hex_digits[digit];
}
Ok, this is where I got:
#include <stdio.h>
#include <stdlib.h>
#define BLOCK 4
void printArray(char*, int);
int main() {
unsigned int x, mask;
int size = sizeof(unsigned int) * 2, i;
char a[size], hexDigits[] = "0123456789ABCDEF";
for (i = 0; i < size; i++)
a[i] = 0;
printf("Enter a positive number: ");
scanf("%u", &x);
for (i = size - 1, mask = ~(~0 << 4); x; i--, x >>= BLOCK) {
a[i] = hexDigits[x & mask];
}
printArray(a, size);
return EXIT_SUCCESS;
}
void printArray(char a[], int n) {
int i;
for (i = 0; i < n; i++)
printf("%c", a[i]);
putchar('\n');
}
I have compiled, it runs and it does the job correctly. I don't know... Should I be worried that this problem was a bit hard for me? At faculty, during exams, we must write our code by hand, on a piece of paper... I don't imagine I would have done this right.
Is there a better (less complicated) way to do this problem? Thank you all for help :)
I would consider the impact of potential padding bits when shifting, as shifting by anything equal to or greater than the number of value bits that exist in an integer type is undefined behaviour.
Perhaps you could terminate the string first using: array[--size] = '\0';, write the smallest nibble (hex digit) using array[--size] = "0123456789ABCDEF"[value & 0x0f], move onto the next nibble using: value >>= 4, and repeat while value > 0. When you're done, return array + size or &array[size] so that the caller knows where the hex sequence begins.

Resources