1

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.

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • 2
    This is a question on C/C++ and so off-topic here. – Yuval Filmus Nov 20 '15 at 10:20
  • This is a question that will require invoking undefined behaviour of your C++ implementation, thus only the compiler writers for that particular architecture will be able to answer. Off-topíc for SE across the board... – vonbrand Nov 20 '15 at 11:49
  • where would this not be off topic? –  Nov 20 '15 at 12:09
  • You don't need it to preserve the value and thus represent a negative value, you only need to preserve the bit pattern. – harold Nov 20 '15 at 12:18
  • The question is not well-defined. How many 1 bits are there in -1? What's the right answer for -1? Infinity? – David Schwartz Nov 20 '15 at 12:30

4 Answers4

1

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;
}
nh_
  • 2,211
  • 14
  • 24
  • And as a final check you could just add one to the number of bits read if number < 0 to account for the additional 1 in the bits of a negative number if that's what you need. – Samidamaru Nov 20 '15 at 12:38
  • @ÍhorMé Your edit brings no actual performance improvements whatsoever: https://godbolt.org/z/H9G7UX. It just makes the code harder to understand. Please refrain from such edits. – idmean Mar 15 '19 at 13:52
  • More efficient loops: `while (unumber != 0) { numOnes += unumber & 1; unumber >>= 1;}` or `while (unumber != 0) { numOnes++; unumber &= unumber - 1; }` – chqrlie Jun 23 '20 at 21:22
  • @chqrlie My comment was directed at the user who suggested this edit: https://stackoverflow.com/review/suggested-edits/22475520. Not sure what you're telling me. – idmean Jun 24 '20 at 08:12
  • @idmean: sorry, I misread your comment and was unaware of the context. ÍhorMé's edit should indeed have been a comment, as I separately suggested too. – chqrlie Jun 25 '20 at 13:14
0

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.

Mark Shevchenko
  • 7,937
  • 1
  • 25
  • 29
0
// 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;
}
balabhi
  • 641
  • 5
  • 5
0

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;
arpit1714
  • 543
  • 6
  • 8
  • I'm afraid `n >> k` has implementation defined behavior for negative `n`. Furthermore the behavior is undefined if type `int` has fewer than 32 bits and the behavior is incorrect for positive values if type `int` is larger than 32 bits... Your approach does not solve the problem in a portable fashion. – chqrlie Jun 23 '20 at 21:16
  • @chqrlie n>>k is defined when n is negative because the negative values are being stored as the 2's compliment , and the code is working fine for negative integers. The value 32 corresponds to the number of bits that can be set accordingly by the user based on the data type , in my case I have taken integer to be 32 bit (although it is machine dependent). – arpit1714 Jun 25 '20 at 04:54
  • C17 **6.5.7 Bitwise shift operators** *The result of `E1 >> E2` is `E1` right-shifted `E2` bit positions. If `E1` has an unsigned type or if `E1` has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1/2^E2. If `E1` has a signed type and a negative value, the resulting value is implementation-defined.* Even if it can be asserted that negative values are represented as 2's complement, the Standard does not mandate the semantics of right shifting. The OP does not specify that `int` has 32 bits either. – chqrlie Jun 25 '20 at 13:50