Как ограничить двоичный код, отображаемый в моем десятичном преобразователе в двоичный?

У меня есть этот код до сих пор:

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.

Итак, есть ли способ ограничить двоичный вывод, чтобы он соответствовал, скажем, наиболее значимому пространству, необходимому для точного отображения его преобразования?

Добро пожаловать в Stack Overflow. Пожалуйста, прочитайте страницы справки, возьмите SO тур, прочитайте о как задавать хорошие вопросы, а также контрольный список этого вопроса.

Some programmer dude 21.02.2019 09:35

Что касается возможного способа решения вашей проблемы (насколько я понимаю), вы можете найти самый высокий ненулевой грызть и начать печать с него.

Some programmer dude 21.02.2019 09:38

На единицу меньше, почему 16? Вы работаете с 17-битными числами?

Antti Haapala 21.02.2019 09:43

я работаю в диапазоне чисел от 0 до 65537. Я только что установил «i = 15», чтобы получить наименьший бит из максимального числа.

Anon Laughingman 21.02.2019 10:01

Это очень странный диапазон. 16-битные целые числа без знака идут от 0 до 65535 (включительно).

Some programmer dude 21.02.2019 10:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
149
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Один из способов сделать это - использовать переменную флага, чтобы проверить, есть ли у нас ненулевой старший бит, и начать печатать 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.

Anon Laughingman 21.02.2019 10:17

@AnonLaughingman Рад помочь, вы можете нажать на зеленую галочку, которая означает, что этот ответ решил вашу проблему.

Sandy 21.02.2019 10:21

спасибо и за эту информацию. теперь я прочь, чтобы задать мой следующий вопрос!

Anon Laughingman 21.02.2019 10:32

Чтобы отсортировать это в группы по 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 пробелах. А если серьезно, то спасибо за всю эту информацию. Я с удовольствием разбираюсь во всем этом.

Anon Laughingman 21.02.2019 12:08

Другие вопросы по теме