Если у вас все еще есть проблемы с конвертацией, может быть полезно рассмотреть пару моментов.Во-первых, вы слишком продумываете преобразование из десятичного в двоичное.Для любого заданного целочисленного значения это значение уже сохраняется в памяти в двоичном виде.
Например, если у вас есть целое число 10
, компьютер сохраняет его как 1010
в памяти.Таким образом, для практических целей все, что вам нужно сделать, это прочитать память для значения и установить значения массива на 1
для каждого бита, равного 1
и 0
для каждого бита, равного 0
.Вы можете даже пойти на один лучше, так как то, что вы, скорее всего, после, это двоичное представление числа, нет необходимости хранить 1 и 0 как полное 4-байтовое целочисленное значение в bin
, почему бы не сделать bin
массив символов и сохранение символов '1'
или '0'
в массиве символов (который при обнуляется ) допускает простую печать двоичного представления в виде строки.
Это обеспечивает несколько преимуществ.Вместо преобразования из базы 10 в базу 2 и делений и вызовов по модулю, необходимых для базового преобразования, вы можете просто сдвинуть decimal
вправо на единицу и проверить, является ли младший значащий бит 0
или 1
и сохраните требуемый символ '0'
или '1'
на основе результатов простой унарной операции and
.
Например, в случае целого числа вы можете определить количество битов, необходимое дляпредставляет любое целочисленное значение в двоичном виде с sizeof (int) * CHAR_BIT
(где CHAR_BIT
- это константа, указанная в limits.h
и указывающая количество битов в символе (например, в байтах)).Для целого числа вы можете использовать:
#include <stdio.h>
#include <limits.h> /* for CHAR_BIT */
#define NBITS sizeof(int) * CHAR_BIT /* constant for bits in int */
Для хранения символьных представлений двоичного числа (или вы можете хранить целые числа 1, 0
при желании), вы можете просто объявить массив символов:
char bin[NBITS + 1] = ""; /* declare storage for NBITS + 1 char */
char *p = bin + NBITS; /* initialize to the nul-terminating char */
(инициализируется со всеми нулями и +1
, чтобы разрешить завершающий нуль символ , чтобы массив мог обрабатываться как строка при заполнении)
ДалееКак вы выяснили, выполняете ли вы базовое преобразование или сдвиг и and
, результирующий порядок значений отдельных битов будет в обратном порядке.Чтобы справиться с этим, вы можете просто объявить указатель, указывающий на последний символ в вашем массиве, и заполнить массив 1с и 0с с конца вперед.
Здесь также символьное / строковое представление облегчает работу,Инициализировав ваш массив со всеми нулями, вы можете начать запись в ваш массив, начиная со следующего за последним символом и работая с конца до начала, чтобы убедиться, что у вас будет строка с нулевым символом в конце, когда вы закончите.Кроме того, независимо от количества битов, составляющих decimal
, у вас всегда остается указатель на начало двоичного представления.
В зависимости от того, как вы перебираете каждый бит в decimal
, вывозможно, придется обрабатывать случай, когда decimal = 0;
отдельно.(поскольку вы выполняете цикл, пока есть биты в decimal
, цикл не будет выполняться, если decimal = 0;
) Простой if
может обработать регистр, а ваш else
может просто зациклить все биты в decimal
:
if (decimal == 0) /* handle decimal == 0 separately */
*--p = '0';
else /* loop shifting decimal right by one until 0 */
for (; decimal && p > bin; decimal >>= 1)
*--p = (decimal & 1) ? '1' : '0'; /* decrement p and set
* char to '1' or '0' */
( примечание: , поскольку p
указывал на нуль-завершающий символ , вы должны уменьшить p
с помощью оператора предварительного уменьшения (например,--p
) перед разыменованием и назначением символа или значения)
Все, что остается, - это вывод вашего двоичного представления, и если это сделано, как указано выше, это просто printf ("%s\n", p);
.Собрав все части вместе, вы можете сделать что-то вроде следующего:
#include <stdio.h>
#include <limits.h> /* for CHAR_BIT */
#define NBITS sizeof(int) * CHAR_BIT /* constant for bits in int */
int main (void) {
int decimal = 0;
char bin[NBITS + 1] = ""; /* declare storage for NBITS + 1 char */
char *p = bin + NBITS; /* initialize to the nul-terminating char */
printf ("enter a integer value: "); /* prompt for input */
if (scanf ("%d", &decimal) != 1) { /* validate ALL user input */
fputs ("error: invalid input.\n", stderr);
return 1;
}
if (decimal == 0) /* handle decimal == 0 separately */
*--p = '0';
else /* loop shifting decimal right by one until 0 */
for (; decimal && p > bin; decimal >>= 1)
*--p = (decimal & 1) ? '1' : '0'; /* decrement p and set
* char to '1' or '0' */
printf ("binary: %s\n", p); /* output the binary string */
return 0;
}
( примечание: комментарий о проверке ВСЕХ пользовательских вводимых данных - особенно при использовании семейства scanf
В противном случае вы можете легко отклониться в неопределенное поведение при случайном вводе чего-то, что не начинается с цифры)
Пример использования / Вывод
$ ./bin/int2bin
enter a integer value: 0
binary: 0
$ ./bin/int2bin
enter a integer value: 2
binary: 10
$ ./bin/int2bin
enter a integer value: 15
binary: 1111
Два дополняют отрицательные значения:
$ ./bin/int2bin
enter a integer value: -15
binary: 11111111111111111111111111110001
Посмотрите вещи и дайте мне знать, если у вас есть какие-либо вопросы, или если вам действительно нужно, чтобы bin
был массивом int
.Наличие целочисленного массива, содержащего отдельные битовые значения, не имеет большого смысла, но если это то, что вам нужно сделать, я с радостью помогу.