Что не так с этим кодом 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