我可以用printf打印十六进制或八进制数字。是否有格式标签打印为二进制或任意基数?

我正在运行gcc。

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

当前回答

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');
    }

}

其他回答

即使是支持%b的运行时库,它似乎也只适用于整数值。

如果您想打印二进制的浮点值,我写了一些代码,您可以在http://www.exploringbinary.com/converting-floating-point-numbers-to-binary-strings-in-c/上找到。

以下是我对这个问题的看法。

与大多数其他例子相比的优点:

使用putchar(),它比printf()更有效,甚至(尽管没有那么多)puts() 分成两部分(预计有内联代码),如果需要,可以提高效率。 基于非常快速的RISC算术运算(包括不使用除法和乘法)

大多数例子的缺点:

代码不是很简单。 Print_binary_size()在不复制的情况下修改输入变量。

注意:此代码的最佳结果依赖于在gcc中使用-O1或更高的值或等效值。

代码如下:

    inline void print_binary_sized(unsigned int number, unsigned int digits) {
        static char ZERO = '0';
        int digitsLeft = digits;
        
        do{
            putchar(ZERO + ((number >> digitsLeft) & 1));
        }while(digitsLeft--);
    }

    void print_binary(unsigned int number) {
        int digitsLeft = sizeof(number) * 8;
        
        while((~(number >> digitsLeft) & 1) && digitsLeft){
            digitsLeft--;
        }
        print_binary_sized(number, digitsLeft);
    }
void PrintBinary( int Value, int Places, char* TargetString)
{
    int Mask;

    Mask = 1 << Places;

    while( Places--) {
        Mask >>= 1; /* Preshift, because we did one too many above */
        *TargetString++ = (Value & Mask)?'1':'0';
    }
    *TargetString = 0; /* Null terminator for C string */
}

调用函数“拥有”字符串…:

char BinaryString[17];
...
PrintBinary( Value, 16, BinaryString);
printf( "yadda yadda %s yadda...\n", BinaryString);

取决于您的CPU, PrintBinary中的大多数操作呈现给一个或很少几个机器指令。

根据@ideasman42在他的回答中的建议,这是一个提供int8、16,32和64版本的宏,重用int8宏以避免重复。

/* --- 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;
}

这个输出:

My Flag 0001011011100001001010110111110101111000100100001111000000101000

为了可读性,您可以更改:#define PRINTF_BINARY_SEPARATOR为#define PRINTF_BINARY_SEPARATOR ","或#define PRINTF_BINARY_SEPARATOR " "

这将输出:

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

or

My Flag 00010110 11100001 00101011 01111101 01111000 10010000 11110000 00101000

使用以下功能:

void conbin(int num){  
        if(num != 0)
        {
            conbin(num >> 1);     
            if (num & 1){
            printf("1");
            }
            else{
            printf("0");
            }
        }
    }