Why does this function not work for negative numbers? - c++

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)

Related

Converting decimal to binary using exponents

I was asked to write code for converting a decimal to its binary form. I have tried several different ways but doesn't gives me the order i need. So i am currently stuck on how to proceed.
I have tried by normally finding the binary comparison but it gives me in the incorrect order, lets say the correct order is 1001100, i just get 0011001. and i have no way of changing the order. I am not allowed to use any other library other than iostream, cmath and string. I am now trying to simply find the conversion using the exponent 2^exponent.
This is what i currently have:
int num, exp,rem;
string biNum;
cout<<"Enter decimal number: "<<endl;
cin>>num;
for (exp = 0; pow(2, exp) < num; exp++) {
}
while (num > 0) {
rem = num % (int) pow(2, exp);
if (rem != 0) {
biNum = biNum + '1';
} else {
biNum = biNum + '0';
}
exp--;
}
cout<<biNum;
return 0;
}
I am currently receiving no result at all.
Here is an example that collects the bits in Least Significant Bit (LSB):
//...
while (num > 0)
{
const char bit = '0' + (num & 1);
biNum += bit;
num = num >> 1;
}
Explanation
The loop continues until the num variable is zero. There is no point in adding extra zeros unless you really want them.
The (num & 1) expression returns 1 if the bit is 1, or 0 if the bit is 0.
This is then added to the character 0 to produce either '0' or '1'.
The variable is declared as const since it won't be modified after declaration (definition).
The newly created character is appended to the bit string.
Finally, the num is right shifted by one bit (because that bit was already processed).
There are many other ways to collect the bits in Most Significant Bit (MSB) order. Those ways are left for the OP and the reader. :-)
Here you go. This outputs the bits in the right order:
#include <iostream>
#include <string>
int main ()
{
unsigned num;
std::string biNum;
std::cin >> num;
while (num)
{
char bit = (num & 1) + '0';
biNum.insert (biNum.cbegin (), bit);
num >>= 1;
}
std::cout << biNum;
return 0;
}
Live demo
You can use a recursive function to print the result in reverse order, avoiding using a container/array, like so:
void to_binary(int num) {
int rem = num % 2;
num = (num - rem) / 2;
if (num < 2){
std::cout << rem << num;
return;
}
to_binary(num);
std::cout << rem;
}
int main()
{
to_binary(100);
}

Use of dynamic bitset to convert decimal numbers

I am solving a leetcode problem, which the output need to be a binary number without abundant digits.
I have the decimal number and I was trying to use bitset to do the conversion.
I wrote a function to return the number of digit given the number n:
int digitNum (int n){
int digit = 0;
while(n!=0){
n/=2;
digit++;
}
return digit;
}
But when I called it,
int digit = digitNum(res);
result = bitset<digit>(res).to_string();
the digit needs to be a constant. I read the boost::bitset, and I don't see how I can use a dynamic bitset to fix my problem.
http://www.boost.org/doc/libs/1_63_0/libs/dynamic_bitset/dynamic_bitset.html
because it's defining each bit by hand. It doesn't convert to binary anymore.
bitset is a template. Any option in <> is generated at compile-time, so they can't take an input from a variable at runtime to choose template parameters. you can use a loop much like your existing one to do the same job as bitset:
string numToBits(int number)
{
if (number == 0)
return "0";
string temp;
int n = (number > 0) ? number : - number;
while (n > 0)
{
temp = string((n & 1) ? "1" : "0") + temp;
n = n / 2;
}
if(number < 0)
temp = "-" + temp;
return temp;
}

Counting number of 1 bits in C++ negative number

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;

How to convert negative number to base P in C++

I have integer num, which can be negative or positive and also I have number P (1 < P <= 9).
What I want to do is to convert num to base-P.
I easily do it when num > 0:
int i = 0;
int A[10000];
while (num != 0)
{
A[i] = num % p;
num /= p;
i++;
}
But I don't know how to achieve it when num < 0.
Check if number is positive or negative, and remember this in the code. If it's negative - multiply the number by -1 and do the same you did to a positive number. When you output the number, you should do this before:
if (sign == -1)
cout << '-';
And then write the rest of the number.
The - sign is not something special to base 10. In general if 90base{10} = 1011010base{2} then -90base{10} = -1011010base{2}. What you are doing here is an extension of two's complement. Two's complement is a method to represent both positive and negative numbers in binary without using a - and is used in computing. Just check whether number is positive or negative and put negative sign. You can use for checking Adrian's answer. But, you can also use the function code that returns -1 for negative values, 0 for zero, 1 for positive values of x
int status (int x) {
int sign = (x > 0) - (x < 0);
return sign;
}

Multiplying two integers given in binary

I'm working on a program that will allow me to multiply/divide/add/subtract binary numbers together. In my program I'm making all integers be represented as vectors of digits.
I've managed to figure out how to do this with addition, however multiplication has got me stumbled and I was wondering if anyone could give me some advice on how to get the pseudo code as a guide for this program.
Thanks in advance!
EDIT: I'm trying to figure out how to create the algorithm for multiplication still to clear things up. Any help on how to figure this algorithm would be appreciated. I usually don't work with C++, so it takes me a bit longer to figure things out with it.
You could also consider the Booth's algorithm if you'd like to multiply:
Booth's multiplication algorithm
Long multiplication in pseudocode would look something like:
vector<digit> x;
vector<digit> y;
total = 0;
multiplier = 1;
for i = x->last -> x->first //start off with the least significant digit of x
total = total + i * y * multiplier
multiplier *= 10;
return total
you could try simulating a binary multiplier or any other circuit that is used in a CPU.
Just tried something, and this would work if you only multiply unsigned values in binary:
unsigned int multiply(unsigned int left, unsigned int right)
{
unsigned long long result = 0; //64 bit result
unsigned int R = right; //32 bit right input
unsigned int M = left; //32 bit left input
while (R > 0)
{
if (R & 1)
{// if Least significant bit exists
result += M; //add by shifted left
}
R >>= 1;
M <<= 1; //next bit
}
/*-- if you want to check for multiplication overflow: --
if ((result >> 32) != 0)
{//if has more than 32 bits
return -1; //multiplication overflow
}*/
return (unsigned int)result;
}
However, that's at the binary level of it... I just you have vector of digits as input
I made this algorithm that uses a binary addition function that I found on the web in combination with some code that first adjusts "shifts" the numbers before sending them to be added together.
It works with the logic that's in this video https://www.youtube.com/watch?v=umqLvHYeGiI
and this is the code:
#include <iostream>
#include <string>
using namespace std;
// This function adds two binary strings and return
// result as a third string
string addBinary(string a, string b)
{
string result = ""; // Initialize result
int s = 0; // Initialize digit sum
int flag =0;
// Traverse both strings starting from last
// characters
int i = a.size() - 1, j = b.size() - 1;
while (i >= 0 || j >= 0 || s == 1)
{
// Computing the sum of the digits from right to left
//x = (condition) ? (value_if_true) : (value_if_false);
//add the fire bit of each string to digit sum
s += ((i >= 0) ? a[i] - '0' : 0);
s += ((j >= 0) ? b[j] - '0' : 0);
// If current digit sum is 1 or 3, add 1 to result
//Other wise it will be written as a zero 2%2 + 0 = 0
//and it will be added to the heading of the string (to the left)
result = char(s % 2 + '0') + result;
// Compute carry
//Not using double so we get either 1 or 0 as a result
s /= 2;
// Move to next digits (more to the left)
i--; j--;
}
return result;
}
int main()
{
string a, b, result= "0"; //Multiplier, multiplicand, and result
string temp="0"; //Our buffer
int shifter = 0; //Shifting counter
puts("Enter you binary values");
cout << "Multiplicand = ";
cin >> a;
cout<<endl;
cout << "Multiplier = ";
cin >> b;
cout << endl;
//Set a pointer that looks at the multiplier from the bit on the most right
int j = b.size() - 1;
// Loop through the whole string and see if theres any 1's
while (j >= 0)
{
if (b[j] == '1')
{
//Reassigns the original value every loop to delete the old shifting
temp = a;
//We shift by adding zeros to the string of bits
//If it is not the first iteration it wont add any thing because we did not "shift" yet
temp.append(shifter, '0');
//Add the shifter buffer bits to the result variable
result = addBinary(result, temp);
}
//we shifted one place
++shifter;
//move to the next bit on the left
j--;
}
cout << "Result = " << result << endl;
return 0;
}