Counting number of 1 bits in C++ negative number - c++

The following function:
int numOnesInBinary(int number) {
int numOnes = 0;
while (number != 0) {
if ((number & 1) == 1) {
numOnes++;
}
number >>= 1;
}
return numOnes;
}
will only work for positive numbers, because in the case of a negative number, it always add a 1 to the leftmost bit when doing the >> operation. In Java we can use >>> instead, but how can we do it in C++?
I read in a book that we can use unsigned integers in C++, but I don't see how since unsigned integers cannot represent negative numbers.

Cast number to unsigned int and perform your counting on that:
int numOnesInBinary(int number) {
int numOnes = 0;
unsigned int unumber = static_cast<unsigned int>(number);
while (unumber != 0) {
if ((unumber & 1) == 1) {
numOnes++;
}
unumber >>= 1;
}
return numOnes;
}

// How about this method, as hinted in "C Book" by K & R.
// Of course better methods are found in MIT hackmem
// http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html
//
int numOnesInBinary(int number) {
int numOnes = 0;
// Loop around and repeatedly clear the LSB by number &= (number -1).
for (; number; numOnes++, number &= (number -1));
return numOnes;
}

Unsigned integer lets to count bits in a simple loop.
Casting from signed to unsigned makes invalid result, if we speak about the values:
char c = -127;
unsigned char u = (unsigned char)c; // 129
But if we speak only about the form, it's not changed:
1 0 0 0 0 0 0 1 == decimal signed -127
1 0 0 0 0 0 0 1 == decimal unsigned 129
So casting to unsigned is just a hack.

count represents the number of set bits in the integer n
if size of integer is 32 bits then
int count =0;
int n = -25 //(given)
for(int k=0;k<32;k++){
if ((n >> k) & 1){
count++;
}
}
return count;

Related

Unsigned function to return digits using any numbers

I'm working on an exercise where I have to program an unsigned
function in C++ --- The function has returned the number of digits
in num and must work on any number.
The issue --- when I do unsigned num is greater than 10 digits, it still
shows 10 as the answer. what am I doing wrong?
unsigned numDigits(unsigned num)
{
if (num == 0)
return 0;
return 1 + numDigits(num / 10);
return (num);
}
int main()
{
unsigned num = 12345678901;
cout << "Number of Digits: " << numDigits(num);
}
unsigned size is:
0 to 65,535 or
0 to 4,294,967,295 (10 digits)
So change your funtion into:
unsigned numDigits(long long unsigned num)
A cheat solution to your problem is also:
std::string dig = std::to_string(num);
std::cout << dig.size();
unsigned getNumDigits(long long unsigned num)
{
if (num < 9 )
return 1;
return 1 + getNumDigits(num / 10 );
}
#ram , thx for pointing out.
Max guaranteed unsigned value is 65535 . Accomodating values more than this will need a bigger (value accomodating) type. Max unsigned value is possible with long long unsigned . A value 0 also mean 1 digit hence comparison against 9 .

Finding the majority of corresponding bits

I am trying to find an efficient way to get the majority of corresponding bit in a group of same sized integers. For example in the given integers:
12 => 1 1 0 0
9 => 1 0 0 1
9 => 1 0 0 1
3 => 0 0 1 1
the majority of bit (column wise) can be represented as:
1 0 0 1
If there are equal number of 1's and 0's (column wise), it should be 1. I would like to achieve this using integers without converting the integer to binary string if possible.
In C, this could be something like this:
unsigned arr[] = { 12, 9, 9, 3 }; // values to loop through
unsigned len = sizeof(arr) / sizeof(arr[0]); // # of values
unsigned result = 0; // collect result here
unsigned bits = sizeof(arr[0]) * 8; // number of bits to consider
unsigned threshold = len / 2 + ((len & 1) ? 1 : 0); // minimum # of 1 to get a 1
unsigned bit = 1 << (bits - 1); // bit mask; point to most significant bit position
for (unsigned pos = 0; pos < bits; pos++) {
unsigned ones = 0;
for (unsigned i = 0; i < len; i++) {
if ((bit & arr[i]) != 0) {
ones++;
}
}
result = (result << 1) + ((ones >= threshold) ? 1 : 0);
bit = bit >> 1;
}
printf("\n%d\n", result);
The outer loop shifts a bitmask from the most-significant to the least-significant end. The inner loop counts the bits set to 1. If the 1 bits exceed a threshold, a 1 is shifted into the result. Otherwise, a 0 is shifted in. At the end, the result holds the majority bits as requested.
This could be further optimized but was not to keep readability up.
Simplified for special case len==4
unsigned arr[] = { 12, 9, 9, 3 }; // values to loop through
unsigned len = sizeof(arr) / sizeof(arr[0]); // # of values
unsigned result = 0; // collect result here
// for len==4, majority means that 2 or more bits are 1
for (unsigned i = 0; i < len - 1; i++)
for (unsigned j = i + 1; j < len; j++) {
result = result | (arr[i] & arr[j]);
}
printf("\n%d\n", result);

need help for write a function that give me all the states of a number

I have a 192-bit number . and I want two write a function that give me all of the states of this number as follows :
1) all the states with one bit 1
2) all the states with two bits 1
3) all the states with three bits 1
.
.
.
and so on till all of the bits will be 1
also I want to write each of this part in a separate files.
I'v just wrote the states that all of the 1-bits are put together.
for example:(for 16-bits number)
0000000000000011----> then I shift the bits to the left. But I can't find a good way to give me all of states of two bits.
(I use miracle library in C for this big number)
do you have any idea?
thank you :)
You could use 6 for-loops (192/32bit) which loop across all the values of a uint32
inside every-for-loop you can multiply the uint32 by some value to get the right value something like this:
for(uint32_t i = 0; i < 0xFFFFFFFF; i++) {
for(uint32_t j = 0; j < 0xFFFFFFFF; j++) {
bignumber = j + 0xFFFFFFFF*i
print(bignumber)
}
}
or if you want to do it really bitwise you could do some bitmasking inside the for-loops
I do not know your functions. but, if you have num and shiftLeft and equals functions, it can be like this
for (int i=0;i<192;i+=2)
{
num->assing(0b11);
num->shiftLeft(i*2);
if (num->andOperand(victim)->equals(num))
{
//this is the number has two consecutive 11, and only
}
if (num->andOperand(victim)->biggerAndEqual(0b11))
{
//this is the number has at least one , two consecutive 11
}
}
As the problem was stated there are ((2 ^ 192) - 1) numbers to print, because all permutations are covered except 0 which contains no 1 bits. That is clearly impossible so the question must be asking for consecutive bits set. As #n.m. wrote, get it working with 4 bits first. Then extend it to 192 bits. To shift a number, you double it. This solution works without doing any bit shifting or multiplication - by addition only (apart from the bit mask in printbits().
#include<stdio.h>
#define BITS 4
unsigned printmask;
void printbits (unsigned num) {
int i;
for (i=0; i<BITS; i++) {
if (num & printmask)
printf ("1");
else
printf ("0");
num = num + num;
}
printf (" ");
}
int main() {
unsigned num, bits;
int m, n;
printmask = 1; // prepare bit mask for printing
for (n=1; n<BITS; n++)
printmask = printmask + printmask;
num = 1;
for (n=0; n<BITS; n++) {
bits = num;
for (m=n; m<BITS; m++) {
printbits (bits);
bits = bits + bits;
}
printf ("\n");
num = num + num + 1;
}
return 0;
}
Program output
0001 0010 0100 1000
0011 0110 1100
0111 1110
1111

C++ convert binary to decimal for bit values greater than 64 bits

I am using this code to convert binary to decimal. But this code will not work for more 64 bits as __int64 holds only 8 bytes. Could you please tell suggest an algorithm to use to convert more than 64 bits to decimal values. Also my end result has to be string. Help is appreciated. Thanks.
int bin2dec(char *bin)
{
__int64 b, k, m, n;
__int64 len, sum = 0;
len = strlen(bin) - 1;
for(k = 0; k <= len; k++)
{
n = (bin[k] - '0'); // char to numeric value
if ((n > 1) || (n < 0))
{
puts("\n\n ERROR! BINARY has only 1 and 0!\n");
return (0);
}
for(b = 1, m = len; m > k; m--)
{
// 1 2 4 8 16 32 64 ... place-values, reversed here
b *= 2;
}
// sum it up
sum = sum + n * b;
}
return(sum);
}
Typically, when dealing with data bigger than what you can store in one integer unit, the solution is one of two things:
Use a character array/string to store the value as "ASCII" (in this one bit per char)
Use multiple integers in an array to store the values, using X bits per element.
There is nothing particularly different about the conversion, just that once you have done X bits, you shift to the next element.
By the way:
int bin2dec(char *bin)
{
int k, n;
int len;
__int64 sum = 0;
len = strlen(bin);
for(k = 0; k < len; k++)
{
n = (bin[k] - '0'); // char to numeric value
if ((n > 1) || (n < 0))
{
puts("\n\n ERROR! BINARY has only 1 and 0!\n");
return (0);
}
// sum it up
sum <<= 1;
sub += n;
}
return(sum);
}
is a bit simpler.
The algorithm is simple: keep dividing by powers of 10 in order to get each 10s place of the value. The trick is being able to store and divide by powers of 10 for numbers bigger than 64 bit. The algorithms for storing big numbers exist and you should find one, though they are not hard to right, they are bigger than is appropriate to type into an answer here at Stackoverflow.
But basically, you create an accumulator bignum, set it to 1 and start multiplying it by 10 until it is bigger in value than your target bignum. Then you divide it by 10 and start the algorithm:
while accum >= 1
divide source/accum place the dividend in your output string.
substract that number time accum from your source.
divide accum by 10 and loop
Do you recognize that algorithm? It is probably how you were taught to do long division in grade school. Well, that's how you "print" a binary number in decimal.
There are lots of ways to improve the performance of this. (Hint, you don't have to work in base 10. Work in base 10^8 for 32-bit ints or base 10^17 for 64-bit ints.) But first you need a library that will subtract, add, multiple, divide and compare bignums.
Of course a bignum library probably already has a toString function.
You can readily store big numbers (in any base) as a std::deque of digits -- using a deque makes it easy to add digits on either end. You can implement basic arithmetic operations on them, which makes it easy to convert binary to decimal using the standard multiply and add digits algorithm:
std::deque<char> &operator *=(std::deque<char> &a, unsigned b)
{
unsigned carry = 0;
for (auto d = a.rbegin(); d != a.rend(); d++) {
carry += (*d - '0') * b;
*d = (carry % 10) + '0';
carry /= 10; }
while (carry > 0) {
a.push_front((carry % 10) + '0');
carry /= 10; }
return a;
}
std::deque<char> &operator +=(std::deque<char> &a, unsigned b)
{
for (auto d = a.rbegin(); b > 0 && d != a.rend(); d++) {
b += (*d - '0');
*d = (b % 10) + '0';
b /= 10; }
while (b > 0) {
a.push_front((b % 10) + '0');
b /= 10; }
return a;
}
std::string bin2dec(char *bin) {
std::deque<char> tmp{'0'};
while (*bin) {
if (*bin != '0' && *bin != '1') {
puts("\n\n ERROR! BINARY has only 1 and 0!\n");
return ""; }
tmp *= 2;
if (*bin++ == '1')
tmp += 1; }
return std::string(tmp.begin(), tmp.end());
}
manually:
int binaryToDec(char *bin)
{
int k, n;
int len=strlen(bin);
int dec = 0;
for(k = 0; k < len; k++)
{
n = (bin[k] - '0');
dec <<= 1;
dec += n;
}
return(dec);
}
you can also consider a bitset:
std::bitset<64> input(*bin);
std::cout<<input.u_long();

Why does this function not work for negative numbers?

I an using the following function to calculate the set bits in an integer, and it works for positive numbers, but not for negative numbers. Can anyone explain why?
int CountSetBits(int number)
{
int count = 0;
while (number > 0)
{
count += (number & 0x01);
number >>= 1;
}
return count;
}
while (number > 0)
Will immediately end (since number < 0 from the onset)
You can force it to treat the number as unsigned:
unsigned int new_number = number;
And then it should work with new_number (this works because of how the sign bit is implemented)