Я пытаюсь преобразовать двоичное число в десятичное. В моем коде цифры будут вводиться как члены массива целых чисел, затем над каждым элементом будут выполняться некоторые математические операции и, наконец, добавление и запись результата в другую переменную. Сначала я хотел собрать свое двоичное число в виде строки, а затем преобразовать в массив int с помощью atoi или strol, но я не мог, поэтому я попробовал этот способ.
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int binToint(int arrName[]);
int binToint(int arrName[]) {
int index;
int length, j, x = 0; //initializing length, x and j to 0
for (index = 0; arrName[index] == 1 || arrName[index] == 0; index++)
++length;
j = length;
for (index = 0; index < length; index++) {
--j;
if (j < 0)
break;
x += arrName[index] * ((int)pow(10, j)); //decimal = binary x 10^index of digit
}
printf("Result: %d", x);
return x;
}
int main(void) {
int tester[] = {1,1,1,0,1,1}; //i used the commas so that each digit will be stored separately
binToint(tester); //calling the function
}
После запуска я не получил никакого вывода, скорее, у меня был пустой экран. Выход должен быть:
Result: 59
Буду рад, если мои ошибки будут замечены и исправлены. Я также буду признателен за оптимизацию моего кода. Спасибо
arrName[index] != '\0'
- arrName
- это массив целых чисел, а не строка с нулевым завершением.
x =+ arrName...
должно быть x += arrName...
?
0b111011 тоже равно 59, а не 29?
длина инициализируется
@AbdurrahmanMuhammadKabir, нет length
, он не инициализирован, он просто объявлен. Его исходное содержание не определено.
любезно интерпретируйте эту длину int, j, x = 0;
Ты хочешь помощи или нет? (Споры об основах синтаксиса здесь вам не помогут.)
Я хочу помочь, пожалуйста. Извини!
Каждая переменная должна быть индивидуально инициализирована. int length = 0, j = 0, x = 0;
Это одна из многих причин, по которым никогда не следует использовать несколько объявлений в одной строке. Эта ошибочная особенность языка C — просто фабрика ошибок. Всегда объявляйте каждую переменную в отдельной строке.
Отвечает ли это на ваш вопрос? Преобразование двоичной строки в числовую строку в десятичное число в C
Помните, что любое число — это просто коэффициенты многочлена для каждой степени основания (или основания). То есть:
3
×102 + 0
×101 + 7
×100 == 3
0
7
== 307
Для двоичной системы счисления не 10, а 2. Итак:
11
Ловкий трюк заключается в том, что вся эта «сила» представляет собой просто повторяющееся умножение, поэтому очень легко построить число, просто начав с самой левой (наиболее значащей) цифры, а затем умножая на систему счисления каждый раз перед добавлением. следующее числовое значение:
multiply, add
0 * 2 = 0, 0 + [1] (first digit) = 1
1 * 2 = 2, 2 + [0] (second digit) = 2
2 * 2 = 4, 4 + [1] (third digit) = 5
5 * 2 = 10, 10 + [1] (fourth digit) = 11 (final answer)
Когда вам дан массив двоичных значений (1
или 0
, а не 1
или 1
), вы можете легко построить свой результат. Начните с 1
и просто умножайте и добавляйте для каждой следующей цифры:
int value = 0;
for (each digit in the input array, left to right)
{
value *= 2;
value += digit;
}
return value;
Переход назад (0
к массиву) усложняется только тем фактом, что вы можете отделять цифры только справа (наименее значащие), но в остальном это так же просто.
Удачи!
Код рискует выйти за пределы массива.
С
int tester[] = {1,1,1,0,1,1};
binToint(tester);
И с int binToint(int arrName[])
for (index = 0; arrName[index] == 1 || arrName[index] == 0; index++)
ничто не помешает arrName[index]
пройти мимо arrName[5]
.
Код должен проходить в длину.
int tester[] = {1,1,1,0,1,1};
int n = sizeof tester/sizeof tester[0];
binToint(n, tester);
А затем повторите:
int binToint(int n, int arrName[]) {
...
for (index = 0; index < n; index++)
Плохая инициализация
Только x
в инициализированном.
// int length, j, x = 0;
int length = 0;
int j = 0;
int x = 0;
Нет обнаружения переполнения
Надежный код будет жаловаться на попытку сформировать значение больше, чем INT_MAX
.
Код может иметь и другие проблемы
Как уже говорили другие, вы не можете вычислить длину массива внутри функции. Длина должна быть передана в функцию.
Я добавил новый параметр, len
.
После этого вычисление значения с побитовым сдвигом становится тривиально простым.
#include <stdio.h>
int binToint(int bits[const], int len)
{
int answer = 0;
for(int i=0; i<len; ++i)
{
answer = (answer << 1) + bits[i];
}
return answer;
}
int main(void) {
int tester[] = {1,1,1,0,1,1};
int result = binToint(tester, 6); //calling the function, including the length.
printf("Result is %d\n", result);
}
Result is 59
Интересно миксовать <<, +
. Я бы ожидал арифметики *, +
или логики <<, |
. Но, скорее всего, компилятор выдаст эффективный код для всех 3.
@chux: Кажется, вы комментируете практически все мои ответы. Иногда проницательно, а иногда и с незначительными моментами.
пожалуйста, почему вы использовали оператор преинкремента ++i вместо постинкремента i++, я запутался
@AbdurrahmanMuhammadKabir: Это действительно не имеет значения. Я изучил предварительный инкремент и использую его по привычке. Я понимаю, что большинство людей учили пост-инкременту и тоже его используют. Но неважно, какой из них используется здесь.
вы не инициализировали
length