Existe um conversor printf para imprimir em formato binário?

Eu posso imprimir com printf como um número hexadecimal ou octal. Existe uma tag de formato para imprimir como base binária ou arbitrária?

Eu estou executando o gcc.

printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n" print("%b\n", 10); // prints "%b\n" 

Hacky mas funciona para mim:

 #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" #define BYTE_TO_BINARY(byte) \ (byte & 0x80 ? '1' : '0'), \ (byte & 0x40 ? '1' : '0'), \ (byte & 0x20 ? '1' : '0'), \ (byte & 0x10 ? '1' : '0'), \ (byte & 0x08 ? '1' : '0'), \ (byte & 0x04 ? '1' : '0'), \ (byte & 0x02 ? '1' : '0'), \ (byte & 0x01 ? '1' : '0') 
 printf("Leading text "BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(byte)); 

Para tipos de múltiplos bytes

 printf("m: "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n", BYTE_TO_BINARY(m>>8), BYTE_TO_BINARY(m)); 

Você precisa de todas as citações extras, infelizmente. Essa abordagem tem os riscos de eficiência de macros (não passe uma function como o argumento para BYTE_TO_BINARY ), mas evita os problemas de memory e várias chamadas de strcat em algumas das outras propostas aqui.

Imprimir binário para qualquer tipo de dados

 //assumes little endian void printBits(size_t const size, void const * const ptr) { unsigned char *b = (unsigned char*) ptr; unsigned char byte; int i, j; for (i=size-1;i>=0;i--) { for (j=7;j>=0;j--) { byte = (b[i] >> j) & 1; printf("%u", byte); } } puts(""); } 

teste

 int main(int argv, char* argc[]) { int i = 23; uint ui = UINT_MAX; float f = 23.45f; printBits(sizeof(i), &i); printBits(sizeof(ui), &ui); printBits(sizeof(f), &f); return 0; } 

Aqui está um rápido truque para demonstrar técnicas para fazer o que você quer.

 #include  /* printf */ #include  /* strcat */ #include  /* strtol */ const char *byte_to_binary(int x) { static char b[9]; b[0] = '\0'; int z; for (z = 128; z > 0; z >>= 1) { strcat(b, ((x & z) == z) ? "1" : "0"); } return b; } int main(void) { { /* binary string to int */ char *tmp; char *b = "0101"; printf("%d\n", strtol(b, &tmp, 2)); } { /* byte to binary string */ printf("%s\n", byte_to_binary(5)); } return 0; } 

Não há um especificador de conversão binária na glibc normalmente.

É possível adicionar tipos de conversão personalizados à família de funções printf () no glibc. Veja register_printf_function para detalhes. Você pode adicionar uma conversão% b personalizada para seu próprio uso, se ela simplificar o código do aplicativo para disponibilizá-la.

Aqui está um exemplo de como implementar um formato printf personalizado no glibc.

Você poderia usar uma pequena mesa para melhorar a velocidade 1 . Técnicas semelhantes são úteis no mundo embarcado, por exemplo, para inverter um byte:

 const char *bit_rep[16] = { [ 0] = "0000", [ 1] = "0001", [ 2] = "0010", [ 3] = "0011", [ 4] = "0100", [ 5] = "0101", [ 6] = "0110", [ 7] = "0111", [ 8] = "1000", [ 9] = "1001", [10] = "1010", [11] = "1011", [12] = "1100", [13] = "1101", [14] = "1110", [15] = "1111", }; void print_byte(uint8_t byte) { printf("%s%s", bit_rep[byte >> 4], bit_rep[byte & 0x0F]); } 

1 Estou me referindo principalmente a aplicativos incorporados em que os otimizadores não são tão agressivos e a diferença de velocidade é visível.

Aqui está uma versão da function que não sofre com problemas de reentrância ou limites no tamanho / tipo do argumento:

 #define FMT_BUF_SIZE (CHAR_BIT*sizeof(uintmax_t)+1) char *binary_fmt(uintmax_t x, char buf[static FMT_BUF_SIZE]) { char *s = buf + FMT_BUF_SIZE; *--s = 0; if (!x) *--s = '0'; for(; x; x/=2) *--s = '0' + x%2; return s; } 

Note que este código funcionaria tão bem para qualquer base entre 2 e 10 se você simplesmente replace os 2s pela base desejada. O uso é:

 char tmp[FMT_BUF_SIZE]; printf("%s\n", binary_fmt(x, tmp)); 

Onde x é qualquer expressão integral.

Com base na resposta de @William Whyte, esta é uma macro que fornece as versões int8 , 16 , 32 e 64 , reutilizando a macro INT8 para evitar a repetição.

 /* --- PRINTF_BYTE_TO_BINARY macro's --- */ #define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c" #define PRINTF_BYTE_TO_BINARY_INT8(i) \ (((i) & 0x80ll) ? '1' : '0'), \ (((i) & 0x40ll) ? '1' : '0'), \ (((i) & 0x20ll) ? '1' : '0'), \ (((i) & 0x10ll) ? '1' : '0'), \ (((i) & 0x08ll) ? '1' : '0'), \ (((i) & 0x04ll) ? '1' : '0'), \ (((i) & 0x02ll) ? '1' : '0'), \ (((i) & 0x01ll) ? '1' : '0') #define PRINTF_BINARY_PATTERN_INT16 \ PRINTF_BINARY_PATTERN_INT8 PRINTF_BINARY_PATTERN_INT8 #define PRINTF_BYTE_TO_BINARY_INT16(i) \ PRINTF_BYTE_TO_BINARY_INT8((i) >> 8), PRINTF_BYTE_TO_BINARY_INT8(i) #define PRINTF_BINARY_PATTERN_INT32 \ PRINTF_BINARY_PATTERN_INT16 PRINTF_BINARY_PATTERN_INT16 #define PRINTF_BYTE_TO_BINARY_INT32(i) \ PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i) #define PRINTF_BINARY_PATTERN_INT64 \ PRINTF_BINARY_PATTERN_INT32 PRINTF_BINARY_PATTERN_INT32 #define PRINTF_BYTE_TO_BINARY_INT64(i) \ PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i) /* --- end macros --- */ #include  int main() { long long int flag = 1648646756487983144ll; printf("My Flag " PRINTF_BINARY_PATTERN_INT64 "\n", PRINTF_BYTE_TO_BINARY_INT64(flag)); return 0; } 

Isso gera:

 My Flag 0001011011100001001010110111110101111000100100001111000000101000 

Para facilitar a leitura, você pode querer adicionar um separador para, por exemplo:

 My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000 

Imprima o bit menos significativo e desloque-o para a direita. Fazer isso até que o inteiro se torne zero imprime a representação binária sem zeros à esquerda, mas em ordem inversa. Usando recursion, a ordem pode ser corrigida facilmente.

 #include  void print_binary(int number) { if (number) { print_binary(number >> 1); putc((number & 1) ? '1' : '0', stdout); } } 

Para mim, esta é uma das soluções mais limpas para o problema. Se você gosta de prefixo 0b e um novo caractere de linha à esquerda, sugiro envolver a function.

Demonstração online

 const char* byte_to_binary( int x ) { static char b[sizeof(int)*8+1] = {0}; int y; long long z; for (z=1LL< 0; z>>=1,y++) { b[y] = ( ((x & z) == z) ? '1' : '0'); } b[y] = 0; return b; } 

Nenhuma das respostas postadas anteriormente é exatamente o que eu estava procurando, então eu escrevi uma. É super simples usar% B com o printf !

  /* * File: main.c * Author: Techplex.Engineer * * Created on February 14, 2012, 9:16 PM */ #include  #include  #include  #include  #include  static int printf_arginfo_M(const struct printf_info *info, size_t n, int *argtypes) { /* "%M" always takes one argument, a pointer to uint8_t[6]. */ if (n > 0) { argtypes[0] = PA_POINTER; } return 1; } /* printf_arginfo_M */ static int printf_output_M(FILE *stream, const struct printf_info *info, const void *const *args) { int value = 0; int len; value = *(int **) (args[0]); //Beginning of my code ------------------------------------------------------------ char buffer [50] = ""; //Is this bad? char buffer2 [50] = ""; //Is this bad? int bits = info->width; if (bits < = 0) bits = 8; // Default to 8 bits int mask = pow(2, bits - 1); while (mask > 0) { sprintf(buffer, "%s", (((value & mask) > 0) ? "1" : "0")); strcat(buffer2, buffer); mask >>= 1; } strcat(buffer2, "\n"); // End of my code -------------------------------------------------------------- len = fprintf(stream, "%s", buffer2); return len; } /* printf_output_M */ int main(int argc, char** argv) { register_printf_specifier('B', printf_output_M, printf_arginfo_M); printf("%4B\n", 65); return (EXIT_SUCCESS); } 

Alguns tempos de execução suportam “% b”, embora isso não seja um padrão.

Veja também aqui uma discussão interessante:

http://bytes.com/forum/thread591027.html

HTH

Este código deve atender às suas necessidades até 64 bits. Eu criei 2 funções pBin & pBinFill. Ambos fazem a mesma coisa, mas o pBinFill preenche os espaços iniciais com o fillChar. A function de teste gera alguns dados de teste e imprime usando a function.

 char* pBinFill(long int x,char *so, char fillChar); // version with fill char* pBin(long int x, char *so); // version without fill #define kDisplayWidth 64 char* pBin(long int x,char *so) { char s[kDisplayWidth+1]; int i=kDisplayWidth; 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[kDisplayWidth+1]; int i=kDisplayWidth; s[i--]=0x00; // terminate string do { // fill in array from right to left 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[kDisplayWidth+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 

Talvez um pouco OT, mas se você precisar disso apenas para depurar entender ou refazer algumas operações binárias que você está fazendo, você pode dar uma olhada no wcalc (uma simples calculadora do console). Com as opções -b você obtém saída binária.

por exemplo

 $ wcalc -b "(256 | 3) e 0xff"
  = 0b11

Eu otimizei a melhor solução para tamanho e C ++, e cheguei a esta solução:

 inline std::string format_binary(unsigned int x) { static char b[33]; b[32] = '\0'; for (int z = 0; z < 32; z++) { b[31-z] = ((x>>z) & 0x1) ? '1' : '0'; } return b; } 

Não há nenhuma function de formatação na biblioteca padrão C para gerar binário assim. Todas as operações de formatação suportadas pela família printf são para textos legíveis por humanos.

A seguinte function recursiva pode ser útil:

 void bin(int n) { /* Step 1 */ if (n > 1) bin(n/2); /* Step 2 */ printf("%d", n % 2); } 

Existe um conversor printf para imprimir em formato binário?

A família printf() só é capaz de imprimir na base 8, 10 e 16 usando os especificadores padrão diretamente. Eu sugiro criar uma function que converta o número em uma string por necessidades particulares do código.


Para imprimir em qualquer base [2-36]

Todas as outras respostas até agora têm pelo menos uma dessas limitações.

  1. Use memory estática para o buffer de retorno. Isso limita o número de vezes que a function pode ser usada como um argumento para printf() .

  2. Alocar memory exigindo o código de chamada para liberar pointers.

  3. Exija que o código de chamada forneça explicitamente um buffer adequado.

  4. Chame printf() diretamente. Isto obriga uma nova function para fprintf() , sprintf() , vsprintf() , etc.

  5. Use um intervalo inteiro reduzido.

O seguinte não possui nenhuma das limitações acima . Requer C99 ou posterior e uso de "%s" . Ele usa um literal composto para fornecer o espaço do buffer. Não tem problemas com várias chamadas em um printf() .

 #include  #include  #define TO_BASE_N (sizeof(unsigned)*CHAR_BIT + 1) // v. compound literal .v #define TO_BASE(x, b) my_to_base((char [TO_BASE_N]){""}, (x), (b)) // Tailor the details of the conversion function as needed // This one does not display unneeded leading zeros // Use return value, not `buf` char *my_to_base(char *buf, unsigned i, int base) { assert(base >= 2 && base < = 36); char *s = &buf[TO_BASE_N - 1]; *s = '\0'; do { s--; *s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i % base]; i /= base; } while (i); // Could employ memmove here to move the used buffer to the beginning return s; } #include  int main(void) { int ip1 = 0x01020304; int ip2 = 0x05060708; printf("%s %s\n", TO_BASE(ip1, 16), TO_BASE(ip2, 16)); printf("%s %s\n", TO_BASE(ip1, 2), TO_BASE(ip2, 2)); puts(TO_BASE(ip1, 8)); return 0; } 

Saída

 1020304 5060708 1000000100000001100000100 101000001100000011100001000 100401404 

Gostei do código do paniq, o buffer estático é uma boa ideia. No entanto, ele falhará se você quiser vários formatos binários em um único printf (), porque ele sempre retorna o mesmo ponteiro e sobrescreve o array.

Aqui está um estilo C que gira o ponteiro em um buffer dividido.

 char * format_binary(unsigned int x) { #define MAXLEN 8 // width of output format #define MAXCNT 4 // count per printf statement static char fmtbuf[(MAXLEN+1)*MAXCNT]; static int count = 0; char *b; count = count % MAXCNT + 1; b = &fmtbuf[(MAXLEN+1)*count]; b[MAXLEN] = '\0'; for (int z = 0; z < MAXLEN; z++) { b[MAXLEN-1-z] = ((x>>z) & 0x1) ? '1' : '0'; } return b; } 

Nenhuma maneira padrão e portátil.

Algumas implementações fornecem itoa () , mas não vai ser na maioria, e tem uma interface um pouco ruim. Mas o código está por trás do link e deve permitir que você implemente seu próprio formatador facilmente.

Imprimir bits de qualquer tipo usando menos código e resources

Essa abordagem tem como atributos:

  • Trabalha com variables ​​e literais.
  • Não itera todos os bits quando não é necessário.
  • Chame printf apenas quando completar um byte (não desnecessariamente para todos os bits).
  • Funciona para qualquer tipo.
  • Trabalha com pouca e grande capacidade de endian (usa #defines do GCC para checar).
  • Usa typeof () que não é padrão C, mas é largamente definido.
 #include  #include  #include  #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define for_endian(size) for (int i = 0; i < size; ++i) #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define for_endian(size) for (int i = size - 1; i >= 0; --i) #else #error "Endianness not detected" #endif #define printb(value) \ ({ \ typeof(value) _v = value; \ __printb((typeof(_v) *) &_v, sizeof(_v)); \ }) void __printb(void *value, size_t size) { uint8_t byte; size_t blen = sizeof(byte) * 8; uint8_t bits[blen + 1]; bits[blen] = '\0'; for_endian(size) { byte = ((uint8_t *) value)[i]; memset(bits, '0', blen); for (int j = 0; byte && j < blen; ++j) { if (byte & 0x80) bits[j] = '1'; byte <<= 1; } printf("%s ", bits); } printf("\n"); } int main(void) { uint8_t c1 = 0xff, c2 = 0x44; uint8_t c3 = c1 + c2; printb(c1); printb((char) 0xff); printb((short) 0xff); printb(0xff); printb(c2); printb(0x44); printb(0x4411ff01); printb((uint16_t) c3); printf("\n"); return 0; } 

Saída

 $ ./printb 11111111 11111111 00000000 11111111 00000000 00000000 00000000 11111111 01000100 00000000 00000000 00000000 01000100 01000100 00010001 11111111 00000001 00000000 01000011 

Eu usei outra abordagem ( bitprint.h ) para preencher uma tabela com todos os bytes (como seqüências de bits) e imprimi-los com base no byte de input / índice. Vale a pena dar uma olhada.

Minha solução:

 long unsigned int i; for(i = 0u; i < sizeof(integer) * CHAR_BIT; i++) { if(integer & LONG_MIN) printf("1"); else printf("0"); integer <<= 1; } printf("\n"); 

Com base na sugestão de @ ideasman42 em sua resposta, esta é uma macro que fornece as versões int8 , 16 , 32 e 64 , reutilizando a macro INT8 para evitar a repetição.

 /* --- PRINTF_BYTE_TO_BINARY macro's --- */ #define PRINTF_BINARY_SEPARATOR #define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c" #define PRINTF_BYTE_TO_BINARY_INT8(i) \ (((i) & 0x80ll) ? '1' : '0'), \ (((i) & 0x40ll) ? '1' : '0'), \ (((i) & 0x20ll) ? '1' : '0'), \ (((i) & 0x10ll) ? '1' : '0'), \ (((i) & 0x08ll) ? '1' : '0'), \ (((i) & 0x04ll) ? '1' : '0'), \ (((i) & 0x02ll) ? '1' : '0'), \ (((i) & 0x01ll) ? '1' : '0') #define PRINTF_BINARY_PATTERN_INT16 \ PRINTF_BINARY_PATTERN_INT8 PRINTF_BINARY_SEPARATOR PRINTF_BINARY_PATTERN_INT8 #define PRINTF_BYTE_TO_BINARY_INT16(i) \ PRINTF_BYTE_TO_BINARY_INT8((i) >> 8), PRINTF_BYTE_TO_BINARY_INT8(i) #define PRINTF_BINARY_PATTERN_INT32 \ PRINTF_BINARY_PATTERN_INT16 PRINTF_BINARY_SEPARATOR PRINTF_BINARY_PATTERN_INT16 #define PRINTF_BYTE_TO_BINARY_INT32(i) \ PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i) #define PRINTF_BINARY_PATTERN_INT64 \ PRINTF_BINARY_PATTERN_INT32 PRINTF_BINARY_SEPARATOR PRINTF_BINARY_PATTERN_INT32 #define PRINTF_BYTE_TO_BINARY_INT64(i) \ PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i) /* --- end macros --- */ #include  int main() { long long int flag = 1648646756487983144ll; printf("My Flag " PRINTF_BINARY_PATTERN_INT64 "\n", PRINTF_BYTE_TO_BINARY_INT64(flag)); return 0; } 

Isso gera:

 My Flag 0001011011100001001010110111110101111000100100001111000000101000 

Para #define PRINTF_BINARY_SEPARATOR a leitura, você pode mudar: #define PRINTF_BINARY_SEPARATOR para #define PRINTF_BINARY_SEPARATOR "," ou #define PRINTF_BINARY_SEPARATOR " "

Isto irá produzir:

 My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000 

ou

 My Flag 00010110 11100001 00101011 01111101 01111000 10010000 11110000 00101000 
 void print_ulong_bin(const unsigned long * const var, int bits) { int i; #if defined(__LP64__) || defined(_LP64) if( (bits > 64) || (bits < = 0) ) #else if( (bits > 32) || (bits < = 0) ) #endif return; for(i = 0; i < bits; i++) { printf("%lu", (*var >> (bits - 1 - i)) & 0x01); } } 

deve funcionar – não testado.

 /* Convert an int to it's binary representation */ char *int2bin(int num, int pad) { char *str = malloc(sizeof(char) * (pad+1)); if (str) { str[pad]='\0'; while (--pad>=0) { str[pad] = num & 1 ? '1' : '0'; num >>= 1; } } else { return ""; } return str; } /* example usage */ printf("The number 5 in binary is %s", int2bin(5, 4)); /* "The number 5 in binary is 0101" */ 

Em seguida, você verá o layout da memory:

 #include  #include  #include  using namespace std; template string binary_text(T dec, string byte_separator = " ") { char* pch = (char*)&dec; string res; for (int i = 0; i < sizeof(T); i++) { for (int j = 1; j < 8; j++) { res.append(pch[i] & 1 ? "1" : "0"); pch[i] /= 2; } res.append(byte_separator); } return res; } int main() { cout << binary_text(5) << endl; cout << binary_text(.1) << endl; return 0; } 

Aqui está uma pequena variação da solução da paniq que usa templates para permitir a impressão de números inteiros de 32 e 64 bits:

 template inline std::string format_binary(T x) { char b[sizeof(T)*8+1] = {0}; for (size_t z = 0; z < sizeof(T)*8; z++) b[sizeof(T)*8-1-z] = ((x>>z) & 0x1) ? '1' : '0'; return std::string(b); } 

E pode ser usado como:

 unsigned int value32 = 0x1e127ad; printf( " 0x%x: %s\n", value32, format_binary(value32).c_str() ); unsigned long long value64 = 0x2e0b04ce0; printf( "0x%llx: %s\n", value64, format_binary(value64).c_str() ); 

Aqui está o resultado:

  0x1e127ad: 00000001111000010010011110101101 0x2e0b04ce0: 0000000000000000000000000000001011100000101100000100110011100000 

Eu só quero postar minha solução. Ele é usado para obter zeros e uns de um byte, mas chamar essa function algumas vezes pode ser usado para blocos de dados maiores. Eu uso para estruturas de 128 bits ou maiores. Você também pode modificá-lo para usar size_t como parâmetro de input e ponteiro para os dados que deseja imprimir, para que ele possa ser independente do tamanho. Mas funciona para mim sair bem como é.

 void print_binary(unsigned char c) { unsigned char i1 = (1 < < (sizeof(c)*8-1)); for(; i1; i1 >>= 1) printf("%d",(c&i1)!=0); } void get_binary(unsigned char c, unsigned char bin[]) { unsigned char i1 = (1 < < (sizeof(c)*8-1)), i2=0; for(; i1; i1>>=1, i2++) bin[i2] = ((c&i1)!=0); } 

Here’s how I did it for an unsigned int

 void printb(unsigned int v) { unsigned int i, s = 1< <((sizeof(v)<<3)-1); // s = only most significant bit at 1 for (i = s; i; i>>=1) printf("%d", v & i || 0 ); } 

A small utility function in C to do this while solving a bit manipulation problem. This goes over the string checking each set bit using a mask (1<

 void printStringAsBinary(char * input) { char * temp = input; int i = 7, j =0;; int inputLen = strlen(input); /* Go over the string, check first bit..bit by bit and print 1 or 0 **/ for (j = 0; j < inputLen; j++) { printf("\n"); while (i>=0) { if (*temp & (1 < < i)) { printf("1"); } else { printf("0"); } i--; } temp = temp+1; i = 7; printf("\n"); } } 

Yet another approach to print in binary: Convert the integer first .

To print 6 in binary, change 6 to 110 , then print "110" .

Bypasses char buf[] issues.
printf() format specifiers, flags, & fields like "%08lu" , "%*lX" still readily usable.
Not only binary (base 2), this method expandable to other bases up to 16.
Limited to smallish integer values.

 #include  #include  #include  unsigned long char_to_bin10(char ch) { unsigned char uch = ch; unsigned long sum = 0; unsigned long power = 1; while (uch) { if (uch & 1) { sum += power; } power *= 10; uch /= 2; } return sum; } uint64_t uint16_to_bin16(uint16_t u) { uint64_t sum = 0; uint64_t power = 1; while (u) { if (u & 1) { sum += power; } power *= 16; u /= 2; } return sum; } void test(void) { printf("%lu\n", char_to_bin10(0xF1)); // 11110001 printf("%" PRIX64 "\n", uint16_to_bin16(0xF731)); // 1111011100110001 }