¿Hay un convertidor de printf para imprimir en formato binario?

5 minutos de lectura

avatar de usuario
Brian

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"

  • No puedes hacer esto, que yo sepa, usando printf. Obviamente, podría escribir un método de ayuda para lograr esto, pero esa no parece la dirección que desea tomar.

    – Ian P.

    21 de septiembre de 2008 a las 20:09

  • No hay un formato predefinido para eso. Debe transformarlo usted mismo en una cadena y luego imprimir la cadena.

    – rslite

    21 de septiembre de 2008 a las 20:10

  • Una búsqueda rápida en Google produjo esta página con información que puede ser útil: foros.macrumors.com/archive/index.php/t-165959.html

    – Ian P.

    21 de septiembre de 2008 a las 20:10

  • No como parte de la biblioteca ANSI Standard C; si está escribiendo código portátil, el método más seguro es crear el suyo propio.

    – tomlogic

    8 de julio de 2010 a las 16:00

  • Una solución estándar y genérica (para cualquier tipo Integral de cualquier longitud) de conversión a cadena binaria en C++: stackoverflow.com/a/31660310/1814353

    – luart

    27/07/2015 a las 18:31

avatar de usuario
William Whyte

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 varios bytes

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

Desafortunadamente, necesita todas las cotizaciones adicionales. Este enfoque tiene los riesgos de eficiencia de las macros (no pase una función como argumento para BYTE_TO_BINARY) pero evita los problemas de memoria y las múltiples invocaciones de strcat en algunas de las otras propuestas aquí.

  • Y tiene la ventaja también de ser invocable varias veces en un printf cuales los que tienen static los búferes no pueden.

    – Patrick Schlüter

    24 de octubre de 2010 a las 10:28

  • Me he tomado la libertad de cambiar el %d para %cporque debería ser aún más rápido (%d tiene que realizar la conversión digit->char, mientras que %c simplemente genera el argumento

    usuario719662

    27 mayo 2016 a las 15:20

  • Publicó una versión ampliada de esta macro con compatibilidad de 16, 32 y 64 bits: stackoverflow.com/a/25108449/432509

    – ideasman42

    21 de junio de 2017 a las 19:57


  • Tenga en cuenta que este enfoque no es compatible con la pila. Asumiendo int es de 32 bits en el sistema, la impresión de un solo valor de 32 bits requerirá espacio para 32 * valores de 4 bytes; total de 128 bytes. Lo cual, dependiendo del tamaño de la pila, puede o no ser un problema.

    – usuario694733

    12 de octubre de 2017 a las 6:47


  • es importante agregar paréntesis alrededor del byte en la macro o podría tener problemas al enviar una operación BYTE_TO_BINARY(a | b) -> a | b & 0x01 != (a | b) & 0x01

    – Iván Hoffmann

    21 de junio de 2019 a las 15:21


avatar de usuario
ideasman42

Basado en la respuesta de @William Whyte, esta es una macro que proporciona int8,16,32 & 64 versiones, reutilizando el INT8 macro para evitar repeticiones.

/* --- 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 da como resultado:

My Flag 0001011011100001001010110111110101111000100100001111000000101000

Para facilitar la lectura, es posible que desee agregar un separador, por ejemplo:

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

Normalmente, no hay un especificador de conversión binaria en glibc.

Es posible agregar tipos de conversión personalizados a la familia de funciones printf() en glibc. Ver register_printf_function para detalles. Puede agregar una conversión %b personalizada para su propio uso, si simplifica el código de la aplicación para que esté disponible.

Aquí hay un ejemplo de cómo implementar un formato printf personalizado en glibc.

avatar de usuario
Kresimir

Tal vez alguien encuentre útil esta solución:

void print_binary(int number, int num_digits) {
    int digit;
    for(digit = num_digits - 1; digit >= 0; digit--) {
        printf("%c", number & (1 << digit) ? '1' : '0');
    }
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad