1

I'm trying to create a simple program to convert a binary number, for example 111100010 to decimal 482. I've done the same in Python, and it works, but I can't find what I'm doing wrong in C++.

When I execute the C++ program, I get -320505788. What have I done wrong?

This is the Python code:

def digit_count(bit_number):
  found = False
  count = 0

  while not found:
    division = bit_number / (10 ** count)

    if division < 1:
      found = True
    else:
      count += 1

  return count

def bin_to_number(bit_number):
  digits = digit_count(bit_number)
  number = 0

  for i in range(digits):
    exp = 10 ** i

    if exp < 10:
      digit = int(bit_number % 10)
      digit = digit * (2 ** i)
      number += digit

    else:
      digit = int(bit_number / exp % 10)
      digit = digit * (2 ** i)
      number += digit

  print(number)
  return number

bin_to_convert = 111100010
bin_to_number(bin_to_convert)

# returns 482

This is the C++ code:

#include <iostream>
#include <cmath>

using namespace std;

int int_length(int bin_number);
int bin_to_int(int bin_number);

int main()
{

    cout << bin_to_int(111100010) << endl;
    return 0;
}

int int_length(int bin_number){
    bool found = false;
    int digit_count = 0;

    while(!found){
        int division = bin_number / pow(10, digit_count);
        if(division < 1){
            found = true;
        }
        else{
            digit_count++;
        }
    }
    return digit_count;
}

int bin_to_int(int bin_number){
    int number_length = int_length(bin_number);

    int number = 0;

    for(int i = 0; i < number_length; i++){
        int e = pow(10, i);
        int digit;

        if(e < 10){
            digit = bin_number % 10;
            digit = digit * pow(2, i);
            number = number + digit;
        }
        else{
            if((e % 10) == 0){
                digit = 0;
            }
            else{
                digit = bin_number / (e % 10);
            }
            digit = digit * pow(2, i);
            number = number + digit;
        }
    }

    return number;

}
Vasco Ferreira
  • 2,151
  • 2
  • 15
  • 21
  • 1
    This looks funny `int binary_to_int(int bit_number)`. The printed representation has little to do with the int value. And theres always the binary literal 0b0010101101010. Also an integer in c++ has a limited range +-2billion is common and seems to be the case for you. – Captain Giraffe Jun 18 '18 at 20:29
  • 3
    `bin_to_int(111100010)` - that is *not* a binary literal, that's a (very large) decimal integer; `0b111100010` would be a binary literal. – Jesper Juhl Jun 18 '18 at 20:32
  • @CaptainGiraffe didn't know there was a binary literal, tried with that, but it still gives wierd results. – Vasco Ferreira Jun 18 '18 at 20:42
  • In C++ `pow` is a floating point function and truncating the result to `int` may introduce a rounding error, especially when the base is not a power of 2. When translating the Python code it would be better to write your own integer exponentiation function (there is no such standard function in C++) – M.M Jun 19 '18 at 01:43

2 Answers2

3

The problem is that you converted this fragment of Python code

else:
  digit = int(bit_number / exp % 10)
  digit = digit * (2 ** i)
  number += digit

into this:

else{
    if((e % 10) == 0){
        digit = 0;
    }
    else{
        digit = bin_number / (e % 10);
    }
    digit = digit * pow(2, i);
    number = number + digit;
}

In other words, you are trying to apply / after applying %, and protect from division by zero in the process.

This is incorrect: you should apply them the other way around, like this:

else{
    digit = (bit_number / e) % 10;
    digit = digit * pow(2, i);
    number = number + digit;
}

Demo 1

Note that the entire conditional is redundant - you can remove it from your for loop:

for(int i = 0; i < number_length; i++){
    int e = pow(10, i);
    int digit = (bit_number / e) % 10;
    digit = digit * pow(2, i);
    number = number + digit;
}

Demo 2

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • You even helped me to rearrange the Python code. Is it normal that when I execute this code on Code::Blocks, the result is different? I'm getting the value `506`. Even in other online (like Repl.it) I'm getting the correct value. I guess I have a problem with the installation of my IDE. – Vasco Ferreira Jun 18 '18 at 20:44
1

One problem is that the 111100010 in main is not a binary literal for 482 base 10 but is actually the decimal value of 111100010. If you are going to use a binary literal there is no need for any of your code, just write it out since an integer is an integer regardless of the representation.

If you are trying to process a binary string, you could do something like this instead

#include <iostream>
#include <algorithm>

using namespace std;

int bin_to_int(const std::string& binary_string);

int main()
{
    cout << bin_to_int("111100010") << endl;
    cout << 0b111100010 << endl;
    return 0;
}

int bin_to_int(const std::string& bin_string){

    //Strings index from the left but bits start from the right so reverse it
    std::string binary = bin_string;
    std::reverse(binary.begin(), binary.end());

    int number_length = bin_string.size();
    //cout << "bits " << number_length << "\n";

    int number = 0;

    for(int i = 0; i <= number_length; i++){
        int bit_value = 1 << i;
        if(binary[i] == '1')
        {
            //cout << "Adding " << bit_value << "\n";
            number += bit_value;
        }
    }

    return number;
}

Note that to use the binary literal you will need to compile for c++14.

user1593858
  • 649
  • 7
  • 12