Puedo imprimir con printf como un número hexadecimal u octal. ¿Hay una etiqueta de formato para imprimir como base binaria o arbitraria?
Estoy ejecutando gcc.
printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
print("%b\n", 10); // prints "%b\n"
Puedo imprimir con printf como un número hexadecimal u octal. ¿Hay una etiqueta de formato para imprimir como base binaria o arbitraria?
Estoy ejecutando gcc.
printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
print("%b\n", 10); // prints "%b\n"
Respuestas:
Hacky pero funciona para mí:
#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últiples bytes
printf("m: "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n",
BYTE_TO_BINARY(m>>8), BYTE_TO_BINARY(m));
Necesitas todas las citas extra desafortunadamente. Este enfoque tiene los riesgos de eficiencia de las macros (no pase una función como argumento BYTE_TO_BINARY) pero evita los problemas de memoria y las múltiples invocaciones de strcat en algunas de las otras propuestas aquí.
printfque los que tienen staticbuffers no pueden.
%da %c, porque debería ser aún más rápido ( %dtiene que realizar la conversión digit-> char, mientras que %csimplemente genera el argumento
inttenga 32 bits, la impresión de un solo valor de 32 bits requerirá espacio para los valores de 32 * 4 bytes; total de 128 bytes. Lo cual, dependiendo del tamaño de la pila, puede o no ser un problema.
Imprimir binario para cualquier tipo de datos
//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("");
}
prueba
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;
}
size_t i; for (i=size; i-- > 0; )evitar size_tvs. intno coincidencia.
ptr(bucle externo); entonces para cada bit el byte actual (bucle interno), enmascare el byte por el bit actual ( 1 << j). Desplace esa derecha dando como resultado un byte que contenga 0 ( 0000 0000b) o 1 ( 0000 0001b). Imprima el byte resultante printf con formato %u. HTH.
>con size_ty no el >=de su comentario para determinar cuándo finalizar el ciclo.
>y minúsculas y >=con tipos sin signo. 0es un caso de borde sin signo y ocurre comúnmente, a diferencia de las matemáticas con signo menos comunes INT_MAX/INT_MIN.
Aquí hay un truco rápido para demostrar técnicas para hacer lo que quieres.
#include <stdio.h> /* printf */
#include <string.h> /* strcat */
#include <stdlib.h> /* 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;
}
strcates un método ineficiente de agregar un único carácter a la cadena en cada pasada del bucle. En su lugar, agregue char *p = b;ay reemplace el bucle interno con *p++ = (x & z) ? '1' : '0'. zdebería comenzar en 128 (2 ^ 7) en lugar de 256 (2 ^ 8). Considere actualizar para llevar un puntero al búfer para usar (por seguridad de subprocesos), similar a inet_ntoa().
strcat()! Estoy de acuerdo en que strcatprobablemente sea más fácil de entender que el incremento posterior de un puntero desreferenciado para la tarea, pero incluso los principiantes necesitan saber cómo usar correctamente la biblioteca estándar. Tal vez usar una matriz indexada para la asignación hubiera sido una buena demostración (y realmente funcionará, ya bque no se restablece a todos ceros cada vez que se llama a la función).
printf("%s + %s = %s", byte_to_binary(3), byte_to_binary(4), byte_to_binary(3+4)).
No hay un especificador de conversión binaria en glibc normalmente.
Es posible agregar tipos de conversión personalizados a la familia de funciones printf () en glibc. Ver register_printf_function para más detalles. Puede agregar una conversión% b personalizada para su propio uso, si simplifica el código de la aplicación para tenerla disponible.
Aquí hay un ejemplo de cómo implementar formatos de impresión personalizados en glibc.
warning: 'register_printf_function' is deprecated [-Wdeprecated-declarations]Hay una nueva función para hacer lo mismo, sin embargo: register_printf_specifier(). Puede encontrar un ejemplo del nuevo uso aquí: codereview.stackexchange.com/q/219994/200418
Puede usar una mesa pequeña para mejorar la velocidad 1 . Técnicas similares son útiles en el mundo incrustado, por ejemplo, para invertir un 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 Me refiero principalmente a aplicaciones integradas donde los optimizadores no son tan agresivos y la diferencia de velocidad es visible.
Imprima el bit menos significativo y muévalo a la derecha. Hacer esto hasta que el entero se convierta en cero imprime la representación binaria sin ceros a la izquierda pero en orden inverso. Usando la recursividad, el orden se puede corregir con bastante facilidad.
#include <stdio.h>
void print_binary(int number)
{
if (number) {
print_binary(number >> 1);
putc((number & 1) ? '1' : '0', stdout);
}
}
Para mí, esta es una de las soluciones más limpias para el problema. Si le gusta el 0bprefijo y un nuevo carácter de línea final, sugiero ajustar la función.
putc('0'+(number&1), stdout);
Sobre la base de la respuesta de @William Whyte, este es un macro que proporciona int8, 16, 32y 64versiones, la reutilización de la INT8macro a la repetición evitar.
/* --- 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 <stdio.h>
int main() {
long long int flag = 1648646756487983144ll;
printf("My Flag "
PRINTF_BINARY_PATTERN_INT64 "\n",
PRINTF_BYTE_TO_BINARY_INT64(flag));
return 0;
}
Esto produce:
My Flag 0001011011100001001010110111110101111000100100001111000000101000
Para facilitar la lectura, puede agregar un separador, por ejemplo:
My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000
PRINTF_BYTE_TO_BINARY_INT#define para usar opcionalmente.
Aquí hay una versión de la función que no sufre problemas de reentrada o límites en el tamaño / tipo del 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;
}
Tenga en cuenta que este código funcionaría igual de bien para cualquier base entre 2 y 10 si solo reemplaza los 2 por la base deseada. El uso es:
char tmp[FMT_BUF_SIZE];
printf("%s\n", binary_fmt(x, tmp));
¿Dónde xestá cualquier expresión integral?
char *a = binary_fmt(x), *b = binary_fmt(y);que no funcionan como se esperaba. Obligar a la persona que llama a pasar un búfer hace explícito el requisito de almacenamiento; la persona que llama es, por supuesto, libre de usar un búfer estático si realmente lo desea, y luego la reutilización del mismo búfer se vuelve explícita. También tenga en cuenta que, en las ABI modernas de PIC, los buffers estáticos generalmente cuestan más código para acceder que los buffers en la pila.
const char* byte_to_binary( int x )
{
static char b[sizeof(int)*8+1] = {0};
int y;
long long z;
for (z=1LL<<sizeof(int)*8-1,y=0; z>0; z>>=1,y++)
{
b[y] = ( ((x & z) == z) ? '1' : '0');
}
b[y] = 0;
return b;
}
'1'y en '0'lugar de 49y 48en su ternario. Además, bdebe tener 9 caracteres de longitud para que el último carácter pueda seguir siendo un terminador nulo.
static char b[9] = {0}2. Declaración movimiento fuera del bucle: int z,y;3. Añadir el cero final: b[y] = 0. De esta manera no se necesita reinitalización.
8s deben ser reemplazados por CHAR_BIT.
Solución rápida y fácil:
void printbits(my_integer_type x)
{
for(int i=sizeof(x)<<3; i; i--)
putchar('0'+((x>>(i-1))&1));
}
Funciona para cualquier tipo de tamaño y para entradas firmadas y sin firmar. El '& 1' es necesario para manejar entradas firmadas ya que el cambio puede hacer la extensión de la señal.
Hay muchas formas de hacer esto. Aquí hay uno súper simple para imprimir 32 bits o n bits desde un tipo de 32 bits con signo o sin signo (sin poner un negativo si está firmado, solo imprime los bits reales) y sin retorno de carro. Tenga en cuenta que i disminuye antes del cambio de bit:
#define printbits_n(x,n) for (int i=n;i;i--,putchar('0'|(x>>i)&1))
#define printbits_32(x) printbits_n(x,32)
¿Qué hay de devolver una cadena con los bits para almacenar o imprimir más tarde? Puede asignar la memoria y devolverla, y el usuario tiene que liberarla, o bien puede devolver una cadena estática, pero se bloqueará si se vuelve a llamar o por otro hilo. Ambos métodos mostrados:
char *int_to_bitstring_alloc(int x, int count)
{
count = count<1 ? sizeof(x)*8 : count;
char *pstr = malloc(count+1);
for(int i = 0; i<count; i++)
pstr[i] = '0' | ((x>>(count-1-i))&1);
pstr[count]=0;
return pstr;
}
#define BITSIZEOF(x) (sizeof(x)*8)
char *int_to_bitstring_static(int x, int count)
{
static char bitbuf[BITSIZEOF(x)+1];
count = (count<1 || count>BITSIZEOF(x)) ? BITSIZEOF(x) : count;
for(int i = 0; i<count; i++)
bitbuf[i] = '0' | ((x>>(count-1-i))&1);
bitbuf[count]=0;
return bitbuf;
}
Llamar con:
// memory allocated string returned which needs to be freed
char *pstr = int_to_bitstring_alloc(0x97e50ae6, 17);
printf("bits = 0b%s\n", pstr);
free(pstr);
// no free needed but you need to copy the string to save it somewhere else
char *pstr2 = int_to_bitstring_static(0x97e50ae6, 17);
printf("bits = 0b%s\n", pstr2);
Ninguna de las respuestas publicadas anteriormente es exactamente lo que estaba buscando, así que escribí una. ¡Es súper simple usar% B con el printf!
/*
* File: main.c
* Author: Techplex.Engineer
*
* Created on February 14, 2012, 9:16 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <printf.h>
#include <math.h>
#include <string.h>
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);
}
char* buffer = (char*) malloc(sizeof(char) * 50);
char *buffer = malloc(sizeof(*buffer) * 50);
Algunos tiempos de ejecución admiten "% b", aunque eso no es un estándar.
También vea aquí para una discusión interesante:
http://bytes.com/forum/thread591027.html
HTH
Este código debe manejar sus necesidades de hasta 64 bits. Creé 2 funciones pBin y pBinFill. Ambos hacen lo mismo, pero pBinFill llena los espacios iniciales con el fillChar. La función de prueba genera algunos datos de prueba, luego los imprime utilizando la función.
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
widthlugar!
¿Hay un convertidor printf para imprimir en formato binario?
La printf()familia solo puede imprimir en base 8, 10 y 16 utilizando directamente los especificadores estándar. Sugiero crear una función que convierta el número en una cadena según las necesidades particulares del código.
Para imprimir en cualquier base [2-36]
Todas las demás respuestas hasta ahora tienen al menos una de estas limitaciones.
Use memoria estática para el búfer de retorno. Esto limita el número de veces que la función puede usarse como argumento para printf().
Asigne memoria que requiere el código de llamada para liberar punteros.
Requerir que el código de llamada proporcione explícitamente un búfer adecuado.
Llamar printf()directamente Esto obliga a una nueva función para la que fprintf(), sprintf(), vsprintf(), etc.
Use un rango entero reducido.
Lo siguiente no tiene ninguna de las limitaciones anteriores . Requiere C99 o posterior y uso de "%s". Utiliza un literal compuesto para proporcionar el espacio del búfer. No tiene problemas con múltiples llamadas en a printf().
#include <assert.h>
#include <limits.h>
#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 <stdio.h>
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));
puts(TO_BASE(ip1, 36));
return 0;
}
Salida
1020304 5060708
1000000100000001100000100 101000001100000011100001000
100401404
A2F44
Tal vez un poco OT, pero si necesita esto solo para depurar para comprender o volver sobre algunas operaciones binarias que está haciendo, puede echar un vistazo a wcalc (una calculadora de consola simple). Con las opciones -b obtienes salida binaria.
p.ej
$ wcalc -b "(256 | 3) y 0xff" = 0b11
ruby -e 'printf("%b\n", 0xabc)', dcseguidas de 2oseguidas de 0x123p, y así sucesivamente.
No hay una función de formateo en la biblioteca estándar de C para generar binarios como ese. Todas las operaciones de formato que admite la familia printf son para texto legible por humanos.
La siguiente función recursiva puede ser útil:
void bin(int n)
{
/* Step 1 */
if (n > 1)
bin(n/2);
/* Step 2 */
printf("%d", n % 2);
}
Optimicé la mejor solución para tamaño y C ++, y llegué a esta solución:
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;
}
std::string), también podría deshacerse de la staticmatriz. La forma más sencilla sería simplemente soltar el staticcalificador y hacer bque la función sea local.
((x>>z) & 0x01) + '0'es suficiente.
Este enfoque tiene como atributos:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#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;
}
$ ./printb
11111111
11111111
00000000 11111111
00000000 00000000 00000000 11111111
01000100
00000000 00000000 00000000 01000100
01000100 00010001 11111111 00000001
00000000 01000011
He usado otro enfoque ( bitprint.h ) para llenar una tabla con todos los bytes (como cadenas de bits) e imprimirlos en función del byte de entrada / índice. Vale la pena echarle un vistazo.
void
print_binary(unsigned int n)
{
unsigned int mask = 0;
/* this grotesque hack creates a bit pattern 1000... */
/* regardless of the size of an unsigned int */
mask = ~mask ^ (~mask >> 1);
for(; mask != 0; mask >>= 1) {
putchar((n & mask) ? '1' : '0');
}
}
Me gustó el código de paniq, el buffer estático es una buena idea. Sin embargo, falla si desea múltiples formatos binarios en un solo printf () porque siempre devuelve el mismo puntero y sobrescribe la matriz.
Aquí hay un menú desplegable de estilo C que gira el puntero en un búfer 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;
}
countalcanza MAXCNT - 1, el siguiente incremento de countlo haría en MAXCNTlugar de cero, lo que provocará un acceso fuera de los límites de la matriz. Deberías haberlo hecho count = (count + 1) % MAXCNT.
MAXCNT + 1llamadas a esta función de una sola vez printf. En general, si desea dar la opción para más de 1 cosa, hágalo infinito. Números como 4 solo pueden causar problemas.
Conversión genérica de una declaración de cualquier tipo integral en la representación de cadena binaria usando la biblioteca estándar :
#include <bitset>
MyIntegralType num = 10;
print("%s\n",
std::bitset<sizeof(num) * 8>(num).to_string().insert(0, "0b").c_str()
); // prints "0b1010\n"
O solo: std::cout << std::bitset<sizeof(num) * 8>(num);
Mi solución:
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");
Sobre la base de la sugerencia de @ ideasman42 en su respuesta, esta es una macro que proporciona int8, 16, 32y 64versiones, la reutilización de la INT8macro para evitar la repetición.
/* --- 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 <stdio.h>
int main() {
long long int flag = 1648646756487983144ll;
printf("My Flag "
PRINTF_BINARY_PATTERN_INT64 "\n",
PRINTF_BYTE_TO_BINARY_INT64(flag));
return 0;
}
Esto produce:
My Flag 0001011011100001001010110111110101111000100100001111000000101000
Para facilitar la lectura, puede cambiar: #define PRINTF_BINARY_SEPARATORa#define PRINTF_BINARY_SEPARATOR "," o#define PRINTF_BINARY_SEPARATOR " "
Esto generará:
My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000
o
My Flag 00010110 11100001 00101011 01111101 01111000 10010000 11110000 00101000
Utilizar:
char buffer [33];
itoa(value, buffer, 2);
printf("\nbinary: %s\n", buffer);
Para obtener más información, consulte Cómo imprimir un número binario a través de printf .
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);
}
}
debería funcionar - no probado.
/* 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" */
A continuación le mostrará el diseño de la memoria:
#include <limits>
#include <iostream>
#include <string>
using namespace std;
template<class T> 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;
}
Aquí hay una pequeña variación de la solución de paniq que usa plantillas para permitir la impresión de enteros de 32 y 64 bits:
template<class T>
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);
}
Y se puede usar 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() );
Aquí está el resultado:
0x1e127ad: 00000001111000010010011110101101
0x2e0b04ce0: 0000000000000000000000000000001011100000101100000100110011100000