-1

While asking for help on a C++ program to convert binary numbers to integers, @dasblinkenlight wrote the following program. Using the Ideone IDE and also Repl.it, I noticed that it returns the expected value 482. However, using a local IDE (Code::Blocks tested in 2 computers), this same program returns the value 506. Why does this happen?

#include <iostream>
#include <cmath>

using namespace std;

int int_length(int bit_number);
int bin_to_int(int bit_number);

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

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

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

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

    int number = 0;

    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;
    }

    return number;

}
Vasco Ferreira
  • 2,151
  • 2
  • 15
  • 21

2 Answers2

2

pow is a floating point function and so there is the possibility of rounding errors. For an overview see Is floating point math broken?

In particular the line:

int e = pow(10, i);

may cause a problem. The calcluation might work out to , say 9999.999999983732 and then when you truncate this to integer you get 9999 rather than 10000, leading to a wrong result.

You could verify this hypothesis by inspecting the value of e for each loop iteration (either with a debugger, or an output statement). There could be a similar problem for the other use of pow(10, digit_count).

One way to fix it is to use a rounding function, although IMO a better solution is to not use pow at all. Instead write a function with a loop for doing integer exponentiation (there is no standard function for that purpose).

IMO the advice you linked to use pow(2, i) is poor. Although powers of 2 will work out exactly on common systems, the reader might not realize that using pow with integers other than a power of 2 has problems. (And C++ does actually have syntax for integer exponentiation of 2, namely 1 << i).

M.M
  • 138,810
  • 21
  • 208
  • 365
0

As indicated by @M.M, writting a custom power function makes the compiler return the expected value. @Some programmer dude, while debugging I noticed the precision error while calculating the power of the numbers.

This is the fully working code:

#include <iostream>

using namespace std;

int int_length(int bit_number);
int bin_to_int(int bit_number);

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

int power(int number, int p){

    if(p < 1){
        return 1;
    }
    else if(p == 1){
        return number;
    }
    else if(p > 1){
        int result = number;
        for(int i = 1; i < p; i++){
            result = result * number;
        }
        return result;
    }

}

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

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

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

    int number = 0;

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

    return number;

}
Vasco Ferreira
  • 2,151
  • 2
  • 15
  • 21