Что не так с этим кодом bin-to-dec?

Поскольку в этом семестре я изучал курс цифровых систем в школе по физике, я решил попробовать применить то, что мы там изучаем, к моей практике программирования с самообучением. Да, мы по какой-то причине этого не делаем. Во всяком случае, ниже мой код:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
int num = 0;
int power = 0; // used to calculate the power of the digit later

vector<int> binVec; // holds binary value
vector<int> decVec; // holds converted dec value

cout << "Input binary number for conversion to its decimal...\n";

while (cin >> num)
{
    binVec.push_back(num);
}


for (vector<int>::size_type i = 0; i<= binVec.size(); i++)
{
    int temp;

    temp = (binVec[i]*2)^power;
    decVec.push_back(temp);

    if (power = 0)
    {
        power = 2;
    }

    else
    {
        power = power * 2;
    }
}

cout << "The decimal value is \n";

for (vector<int>::size_type j = 0; j<= decVec.size(); j++)
{
    cout << decVec[j];
}

return 0;


 }

Излишне говорить, что это не будет работать правильно. Вначале я сделал несколько глупых ошибок, но вот уже около получаса, когда я этим ломаю голову, получаю странные результаты. Например, когда я ввожу простой бин (10) и ожидаю a (2)dec, я получаю строку чисел, начинающуюся с 2, например 20006721. Кроме того, во время работы программы мой компилятор отправляет сообщение об ошибке. Что может быть не так?

Я знаю, что мой код отстой и не очень хорошо оптимизирован, поэтому любая обратная связь или выговор будут высоко цениться!

5 ответов

Ваш алгоритм ошибочен. Например, вы выводите одну десятичную цифру на двоичную цифру. Однако для большинства двоичных чисел длина десятичного числа будет меньше.

Кроме того, оператор "^" является двоичным оператором XOR в C++, а не оператором степени.

Вместо вашего основного цикла я бы предложил что-то вроде этого:

int decimalNumber = 0;
for (vector<int>::size_type i = 0; i < binVec.size(); i++)
{
    // Note that I changed "less or equal" to "less than"
    decimalNumber *= 2;
    decimalNumber += (binVec[i]);
}
cout << decimalNumber;

У вас есть опечатка в заявлении if:

if (power = 0)

Вам нужно использовать == для сравнения:

if (power == 0)

Кроме того, в ваших циклах for вы выполняете его один раз для многих:

i <= binVec.size();

Массивы индексируются от 0 до размера - 1; так делать <= делает причиной неопределенного поведения для доступа к адресу вне диапазона вектора. Измените это на:

i < binVec.size();

Был указан ряд ошибок. Еще не было упомянуто, что вы делаете что-то довольно странное, а именно: берете XOR с ^ оператор. Интересно, если вы хотели использовать его как power операция вместо?

Вот предлагаемое преобразование - с использованием основных строковых операций.

char* inputString = "101001010";
int ii, dec=0;
for(ii=0; ii<strlen(inputString); ii++) {
  if(*(inputString+ii)=='1') {
    dec = 2 * dec + 1;
  }
  else {
    dec = 2 * dec;
  }
}
printf("the conversion to digital is %d\n", dec);

Альтернатива - использование факта, что '0' и '1' находятся рядом друг с другом в таблице ASCII:

char* inputString = "101001010";
int ii, dec=0;
for(ii=0; ii<strlen(inputString); ii++) {
  dec = 2 * dec + (int)(inputString[ii]-'0');
}
printf("the conversion to digital is %d\n", dec);

Более короткая версия с использованием алгоритма накопления () из STL:

#include <iostream>
#include <numeric>
#include <iterator>

using namespace std;

int main()
{
    cout << "Input binary number for conversion to its decimal..." << endl;
    cout << "The decimal value is: " 
         << accumulate(istream_iterator<bool>(cin), istream_iterator<bool>(), 0, 
                       [](int a, int b) { return (a << 1) + b; }) 
         << endl;
}

У вас есть пара простых синтаксических / семантических ошибок и концептуальная проблема, которую вы хотите рассмотреть. Во-первых, будьте внимательны при проверке соответствия / равенства, вам действительно не нужно начинать питание с нуля, а с 1 (так как 2^0 = 1),

Вот часть вашего кода, исправлена,

int main()
{
    int num = 0;
    int bits=0; // you could use bitshift, rather than multiply
    int power=1; // 2^0 = 1, so start power at 1, not 0

Вы в цикле конвертируете каждую битовую позицию в число, но вы не накапливаете их, учитывайте результаты push_back(temp) в сравнении с bac +=temp

    int temp;
    int accum=0;
    bitpos=0; power=1;
    for (vector<int>::size_type i=0; i<binVec.size(); i++)
    {
        temp = (binVec[i])*power;
        decVec.push_back(temp);
        accum += (binVec[i])<<bitpos;
        bitpos++; power*=2;
    }

Поскольку вы конвертируете каждую десятичную цифру, у вас есть список десятичных значений, но это не однозначные числа, а степени двух (2^n) в зависимости от положения в векторе. Вы можете предпочесть значение, хранящееся в накопителе (ulator). Это ясно, когда вы смотрите на результаты, печатая запятую "," между каждым элементом вектора,

    cout << "The decimal values are ";
    for (vector<int>::size_type j=0; j<decVec.size(); j++)
    {
        cout << decVec[j] << ",";
    }
    cout<<endl;
    cout << "The decimal value is \n" << accum << endl;

Результаты,

./bin2dec
Input binary number for conversion to its decimal: 1 1 1 1 1 1 1 0
The decimal values are 1,2,4,8,16,32,64,0,
The decimal value is 
127

Это иллюстрирует ваш последний концептуальный пункт, который заключается в том, что ваша программа считает самую левую цифру наименее значимой, что может быть вашим намерением, но противоречивым. Это можно исправить, запустив power/bitpos с самого правого значения,

    int temp;
    int accum=0;
    //bitpos=0; power=1;
    bitpos=(int)binVec.size()-1; power=2<<bitpos;
    for (vector<int>::size_type i=0; i<binVec.size(); i++)
    {
        temp = (binVec[i])<<bitpos;
        accum += (binVec[i])<<bitpos;
        decVec.push_back(temp);
        //bitpos++; power*=2;
        bitpos--; power/=2;
    }   

Что дает более ожидаемый результат,

 ./bin2dec
Input binary number for conversion to its decimal: 1 1 1 1 1 1 1 0
The decimal values are 128,64,32,16,8,4,2,0,
The decimal value is 
254
Другие вопросы по тегам