У меня есть этот код до сих пор:
for ( int i = 16; i >=0; i--){
int k = n >> i;
if (k & 1)
printf("1");
else
printf("0");
}
Я очень новичок в C, и я работаю над преобразователем десятичных чисел в двоичные для класса. Пока это то, что я нашел, что работает в пределах моих параметров. Единственная проблема заключается в том, что мне нужен этот код ТОЛЬКО для вывода двоичного файла на MSD, который он получил.
Например, если у меня есть десятичное число 15, оно должно отображать 1111 в двоичном виде, а если у меня есть десятичное число 16, оно должно отображать только следующий набор из 4 выше этого, поэтому 00010000.
На данный момент я могу установить сумму на все, что захочу, например, i = 16, но это покажет всего 15 пробелов. где, как если бы я поставил маленькое десятичное число, я не хочу, чтобы моя программа показывала все лишние ненужные 0.
Итак, есть ли способ ограничить двоичный вывод, чтобы он соответствовал, скажем, наиболее значимому пространству, необходимому для точного отображения его преобразования?
Что касается возможного способа решения вашей проблемы (насколько я понимаю), вы можете найти самый высокий ненулевой грызть и начать печать с него.
На единицу меньше, почему 16? Вы работаете с 17-битными числами?
я работаю в диапазоне чисел от 0 до 65537. Я только что установил «i = 15», чтобы получить наименьший бит из максимального числа.
Это очень странный диапазон. 16-битные целые числа без знака идут от 0 до 65535 (включительно).





Один из способов сделать это - использовать переменную флага, чтобы проверить, есть ли у нас ненулевой старший бит, и начать печатать 0 только после того, как мы встретим ненулевой старший бит, например.
int flag
for ( int i = 16; i >=0; i--)
{
int k = n >> i;
if (k & 1){
printf("1");
flag = 1;
}else{
if (flag)
printf("0");
}
это работало удивительно хорошо! Спасибо огромное. на одну проблему меньше, о которой мне нужно беспокоиться, теперь мне просто нужно выяснить, как получить их в пробелах по 4.
@AnonLaughingman Рад помочь, вы можете нажать на зеленую галочку, которая означает, что этот ответ решил вашу проблему.
спасибо и за эту информацию. теперь я прочь, чтобы задать мой следующий вопрос!
Чтобы отсортировать это в группы по 4, вам нужно работать по кусочкам. Функция, которая печатает полубайт (значение от 0 до 15 dec), может выглядеть так:
void print_bin_nibble (uint8_t ls_nibble)
{
for(size_t i=0; i<4; i++)
{
uint8_t bitmask = 1u << (4-1-i);
printf("%c", (ls_nibble & bitmask) ? '1' : '0');
}
printf(" ");
}
Теперь, если вы хотите распечатать данные по полубайтам, пропуская начальные нули для полубайтов, равных 0000 bin, вам нужно отслеживать, следует ли пропускать печать с логическим флагом. Логика будет такой:
if (nibble==0 && remove_zeroes)
{
; // do nothing
}
else
{
remove_zeroes = false;
print_bin_nibble(nibble);
}
Что можно переписать как (законы Де Моргана):
if (nibble != 0 || !remove_zeroes)
{
remove_zeroes = false;
print_bin_nibble(nibble);
}
Дальнейшее рассмотрение при печати числа - порядок следования байтов процессора. Существуют различные (плохие) способы перебора целого числа байт за байтом, например, использование арифметики указателей или объединений. Но тогда вывод будет зависеть от порядка следования байтов и выглядеть странно на машинах с прямым порядком байтов. Используя битовые сдвиги, мы полностью устраняем эту проблему переносимости, поскольку они не зависят от порядка следования байтов.
Например, имея 32-битное целое число u32, мы можем замаскировать отдельные байты следующим образом:
(u32 >> (24-n*8)) & 0xFF
где n — номер байта от 0 до 3. В итоге мы сдвигаем 24 бита для n=0, 16 бит для n=1, 8 бит для n=2 и 0 бит для n=3.
Полный пример:
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
void print_bin_nibble (uint8_t ls_nibble)
{
for(size_t i=0; i<4; i++)
{
uint8_t bitmask = 1u << (4-1-i);
printf("%c", (ls_nibble & bitmask) ? '1' : '0');
}
printf(" ");
}
void print_bin32 (uint32_t u32)
{
bool remove_zeroes = true;
for(size_t i=0; i<sizeof(u32); i++)
{
uint8_t byte = (u32 >> (24-i*8)) & 0xFF;
uint8_t nibble;
nibble = (uint32_t)byte >> 4;
if (nibble != 0 || !remove_zeroes)
{
remove_zeroes = false;
print_bin_nibble(nibble);
}
nibble = byte & 0xF;
if (nibble != 0 || !remove_zeroes)
{
print_bin_nibble(nibble);
}
}
printf("\n");
}
int main (void)
{
print_bin32(16);
print_bin32(0xDEADBEEF);
print_bin32(0xABBA);
}
Вывод:
0001 0000
1101 1110 1010 1101 1011 1110 1110 1111
1010 1011 1011 1010
Ну, это совершенно за пределами моего понимания программирования на C на данный момент, но я могу кое-что понять. тем не менее, я ценю информацию, но я шокирован тем, что не кажется более простым способом просто отсортировать созданное вами двоичное число с шагом 4. не обязательно разбивать его на 4-е, а просто ограничить его 4, 8 , 16, 32, если он попадает в этот диапазон. это имеет больше смысла? например, если это число от 1 до 15, я бы хотел, чтобы оно отображалось в 4 пробелах. А если серьезно, то спасибо за всю эту информацию. Я с удовольствием разбираюсь во всем этом.
Добро пожаловать в Stack Overflow. Пожалуйста, прочитайте страницы справки, возьмите SO тур, прочитайте о как задавать хорошие вопросы, а также контрольный список этого вопроса.