Отобразить двоичное представление числа в C? [дубликат]

Можно ли реализовать функцию pad_Foo ()? 6.2.6 Представление типов:

6 Когда значение сохраняется в объекте типа структуры или объединения, в том числе в объекте-члене, байты представления объекта, которые соответствуют любому байты заполнения принимают неопределенные значения . 51)

и

51) Таким образом, например, при назначении структуры не нужно копировать какие-либо биты заполнения.

Таким образом, стандарт четко гласит: значением отступа нельзя управлять.

В конкретной системе (платформа, ОС, компилятор) это возможно. В качестве примера из моей системы:

# include <stdio.h>
# include <string.h>

struct s
{
  char c;
  int n;
};

void dump_struct(struct s * p)
{
  unsigned char * u = (unsigned char *)p;
  for (size_t i=0; i < sizeof *p; ++i) printf("%02x ", u[i]);
  printf("\n");
}

int main(){
  printf("sizeof(struct s)=%zu sizeof(char)=%zu sizeof(int)=%zu padding=%zu\n",
         sizeof(struct s), 
         sizeof(char), 
         sizeof(int), 
         sizeof(struct s) - sizeof(char) - sizeof(int));

  struct s sa;
  memset(&sa, 'A', sizeof sa);
  sa.c = '8';
  sa.n = 42;
  dump_struct(&sa);

  struct s sb;
  memset(&sb, 'B', sizeof sa);
  sb.c = '8';
  sb.n = 42;
  dump_struct(&sb);
}

Вывод:

sizeof(struct s)=8 sizeof(char)=1 sizeof(int)=4 padding=3
38 41 41 41 2a 00 00 00
38 42 42 42 2a 00 00 00
   ^^^^^^^^
    notice

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

Добавление такого кода в main:

  unsigned char * u = (unsigned char *)&sb.c;
  u += sizeof sb.c;
  while(u < (unsigned char *)&sb.n)
  {
    *u = 'C';
    ++u;
  }
  dump_struct(&sb);

напечатает дополнительную строку:

38 43 43 43 2a 00 00 00

Итак, еще раз - в моей конкретной системе - отступы были изменены. [ 1118]

6
задан Community 23 May 2017 в 12:10
поделиться

7 ответов

Да (пишут Ваше собственное), что-то как следующая полная функция.

#include <stdio.h> /* only needed for the printf() in main(). */
#include <string.h>

/* Create a string of binary digits based on the input value.
   Input:
       val:  value to convert.
       buff: buffer to write to must be >= sz+1 chars.
       sz:   size of buffer.
   Returns address of string or NULL if not enough space provided.
*/
static char *binrep (unsigned int val, char *buff, int sz) {
    char *pbuff = buff;

    /* Must be able to store one character at least. */
    if (sz < 1) return NULL;

    /* Special case for zero to ensure some output. */
    if (val == 0) {
        *pbuff++ = '0';
        *pbuff = '\0';
        return buff;
    }

    /* Work from the end of the buffer back. */
    pbuff += sz;
    *pbuff-- = '\0';

    /* For each bit (going backwards) store character. */
    while (val != 0) {
        if (sz-- == 0) return NULL;
        *pbuff-- = ((val & 1) == 1) ? '1' : '0';

        /* Get next bit. */
        val >>= 1;
    }
    return pbuff+1;
}

Добавьте это основное в конец его для наблюдения его в операции:

#define SZ 32
int main(int argc, char *argv[]) {
    int i;
    int n;
    char buff[SZ+1];

    /* Process all arguments, outputting their binary. */
    for (i = 1; i < argc; i++) {
        n = atoi (argv[i]);
        printf("[%3d] %9d -> %s (from '%s')\n", i, n,
            binrep(n,buff,SZ), argv[i]);
    }

    return 0;
}

Выполните его с "progname 0 7 12 52 123" добираться:

[  1]         0 -> 0 (from '0')
[  2]         7 -> 111 (from '7')
[  3]        12 -> 1100 (from '12')
[  4]        52 -> 110100 (from '52')
[  5]       123 -> 1111011 (from '123')
12
ответ дан 8 December 2019 в 02:00
поделиться

На основе ответа dirkgently, но исправления его двух ошибок и всегда печати постоянного числа цифр:

void printbits(unsigned char v) {
  int i; // for C89 compatability
  for(i = 7; i >= 0; i--) putchar('0' + ((v >> i) & 1));
}
24
ответ дан 8 December 2019 в 02:00
поделиться

Нет никакого прямого пути (т.е. использование printf или другая стандартная библиотечная функция) для печати его. Необходимо будет записать собственную функцию.

/* This code has an obvious bug and another non-obvious one :) */
void printbits(unsigned char v) {
   for (; v; v >>= 1) putchar('0' + (v & 1));
}

При использовании терминала можно использовать коды управления для распечатывания байтов в естественном порядке:

void printbits(unsigned char v) {
    printf("%*s", (int)ceil(log2(v)) + 1, ""); 
    for (; v; v >>= 1) printf("\x1b[2D%c",'0' + (v & 1));
}
28
ответ дан 8 December 2019 в 02:00
поделиться

Используйте справочную таблицу, как:

char *table[16] = {"0000", "0001", .... "1111"};

затем распечатайте каждое откусывание как это

printf("%s%s", table[a / 0x10], table[a % 0x10]);

Конечно, можно использовать всего одну таблицу, но это будет незначительно быстрее и слишком большим.

4
ответ дан 8 December 2019 в 02:00
поделиться

Этот код должен обработать Ваши потребности до 64 битов.



char* pBinFill(long int x,char *so, char fillChar); // version with fill
char* pBin(long int x, char *so);                    // version without fill
#define width 64

char* pBin(long int x,char *so)
{
 char s[width+1];
 int    i=width;
 s[i--]=0x00;   // terminate string
 do
 { // fill in array from right to left
  s[i--]=(x & 1) ? '1':'0';  // determine bit
  x>>=1;  // shift right 1 bit
 } while( x > 0);
 i++;   // point to last valid character
 sprintf(so,"%s",s+i); // stick it in the temp string string
 return so;
}

char* pBinFill(long int x,char *so, char fillChar)
{ // fill in array from right to left
 char s[width+1];
 int    i=width;
 s[i--]=0x00;   // terminate string
 do
 {
  s[i--]=(x & 1) ? '1':'0';
  x>>=1;  // shift right 1 bit
 } while( x > 0);
 while(i>=0) s[i--]=fillChar;    // fill with fillChar 
 sprintf(so,"%s",s);
 return so;
}

void test()
{
 char so[width+1]; // working buffer for pBin
 long int   val=1;
 do
 {
   printf("%ld =\t\t%#lx =\t\t0b%s\n",val,val,pBinFill(val,so,0));
   val*=11; // generate test data
 } while (val < 100000000);
}

Output:
00000001 = 0x000001 =   0b00000000000000000000000000000001
00000011 = 0x00000b =   0b00000000000000000000000000001011
00000121 = 0x000079 =   0b00000000000000000000000001111001
00001331 = 0x000533 =   0b00000000000000000000010100110011
00014641 = 0x003931 =   0b00000000000000000011100100110001
00161051 = 0x02751b =   0b00000000000000100111010100011011
01771561 = 0x1b0829 =   0b00000000000110110000100000101001
19487171 = 0x12959c3 =  0b00000001001010010101100111000011
3
ответ дан 8 December 2019 в 02:00
поделиться

Необходимо записать собственное преобразование. Только десятичное число, шестнадцатеричные и восьмеричные числа поддерживаются со спецификаторами формата.

2
ответ дан 8 December 2019 в 02:00
поделиться

Нет никакого прямого спецификатора формата для этого на языке C. Хотя я записал этот быстрый отрывок Python, чтобы помочь Вам понять этап процесса под шагом к самокрутке.

#!/usr/bin/python

dec = input("Enter a decimal number to convert: ")
base = 2
solution = ""

while dec >= base:
    solution = str(dec%base) + solution
    dec = dec/base
if dec > 0:
    solution = str(dec) + solution

print solution

Объясненный:

декабрь = вход ("Вводят десятичный номер для преобразования":) - предлагают пользователю числовой вход (существует несколько способов сделать это в C через scanf, например),

базируйтесь = 2 - указывают, что наша база 2 (двоичный файл)

решение = "" - создает пустую строку, в которой мы свяжем наше решение

в то время как декабрь> = основа: - в то время как наше число больше, чем вводимая основа

решение = ул. (dec%base) + решение - получает модуль числа к основе и добавляет его к началу нашей строки (мы должны добавить числа справа налево с помощью подразделения и метода остатка). ул. () функция преобразовывает результат операции к строке. Вы не можете связать целые числа со строками в Python без преобразования типов.

декабрь = декабрь/основа - делит десятичное число на основу в подготовке для взятия следующего модуля

если декабрь> 0: решение = ул. (декабрь) + решение - если что-нибудь перенесено, добавьте его к началу (это будет 1, если что-либо),

решение для печати - печатает заключительное число

2
ответ дан 8 December 2019 в 02:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: