我可以用printf打印十六进制或八进制数字。是否有格式标签打印为二进制或任意基数?
我正在运行gcc。
printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
printf("%b\n", 10); // prints "%b\n"
我可以用printf打印十六进制或八进制数字。是否有格式标签打印为二进制或任意基数?
我正在运行gcc。
printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
printf("%b\n", 10); // prints "%b\n"
当前回答
即使是支持%b的运行时库,它似乎也只适用于整数值。
如果您想打印二进制的浮点值,我写了一些代码,您可以在http://www.exploringbinary.com/converting-floating-point-numbers-to-binary-strings-in-c/上找到。
其他回答
c
// Based on https://stackoverflow.com/a/112956/1438550
#include <stdio.h>
#include <stdint.h>
const char *int_to_binary_str(int x, int N_bits){
static char b[512];
char *p = b;
b[0] = '\0';
for(int i=(N_bits-1); i>=0; i--){
*p++ = (x & (1<<i)) ? '1' : '0';
if(!(i%4)) *p++ = ' ';
}
return b;
}
int main() {
for(int i=31; i>=0; i--){
printf("0x%08X %s \n", (1<<i), int_to_binary_str((1<<i), 32));
}
return 0;
}
期望的行为:
Run:
gcc -pthread -Wformat=0 -lm -o main main.c; ./main
Output:
0x80000000 1000 0000 0000 0000 0000 0000 0000 0000
0x40000000 0100 0000 0000 0000 0000 0000 0000 0000
0x20000000 0010 0000 0000 0000 0000 0000 0000 0000
0x10000000 0001 0000 0000 0000 0000 0000 0000 0000
0x08000000 0000 1000 0000 0000 0000 0000 0000 0000
0x04000000 0000 0100 0000 0000 0000 0000 0000 0000
0x02000000 0000 0010 0000 0000 0000 0000 0000 0000
0x01000000 0000 0001 0000 0000 0000 0000 0000 0000
0x00800000 0000 0000 1000 0000 0000 0000 0000 0000
0x00400000 0000 0000 0100 0000 0000 0000 0000 0000
0x00200000 0000 0000 0010 0000 0000 0000 0000 0000
0x00100000 0000 0000 0001 0000 0000 0000 0000 0000
0x00080000 0000 0000 0000 1000 0000 0000 0000 0000
0x00040000 0000 0000 0000 0100 0000 0000 0000 0000
0x00020000 0000 0000 0000 0010 0000 0000 0000 0000
0x00010000 0000 0000 0000 0001 0000 0000 0000 0000
0x00008000 0000 0000 0000 0000 1000 0000 0000 0000
0x00004000 0000 0000 0000 0000 0100 0000 0000 0000
0x00002000 0000 0000 0000 0000 0010 0000 0000 0000
0x00001000 0000 0000 0000 0000 0001 0000 0000 0000
0x00000800 0000 0000 0000 0000 0000 1000 0000 0000
0x00000400 0000 0000 0000 0000 0000 0100 0000 0000
0x00000200 0000 0000 0000 0000 0000 0010 0000 0000
0x00000100 0000 0000 0000 0000 0000 0001 0000 0000
0x00000080 0000 0000 0000 0000 0000 0000 1000 0000
0x00000040 0000 0000 0000 0000 0000 0000 0100 0000
0x00000020 0000 0000 0000 0000 0000 0000 0010 0000
0x00000010 0000 0000 0000 0000 0000 0000 0001 0000
0x00000008 0000 0000 0000 0000 0000 0000 0000 1000
0x00000004 0000 0000 0000 0000 0000 0000 0000 0100
0x00000002 0000 0000 0000 0000 0000 0000 0000 0010
0x00000001 0000 0000 0000 0000 0000 0000 0000 0001
下面是我对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 );
}
打印任何数据类型的二进制
// 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("");
}
测试:
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;
}
使用更少的代码和资源打印任何类型的位
这种方法有以下属性:
使用变量和字面量。 没有必要时不迭代所有位。 只在完成一个字节时调用printf(不必对所有位都调用)。 适用于任何类型。 使用大小字节序(使用GCC #定义进行检查)。 可以与char不是字节(8位)的硬件一起工作。(谢谢大家@supercat) 使用typeof(),它不是C标准的,但在很大程度上是定义的。
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <limits.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)); \
})
#define MSB_MASK 1 << (CHAR_BIT - 1)
void __printb(void *value, size_t size)
{
unsigned char uc;
unsigned char bits[CHAR_BIT + 1];
bits[CHAR_BIT] = '\0';
for_endian(size) {
uc = ((unsigned char *) value)[i];
memset(bits, '0', CHAR_BIT);
for (int j = 0; uc && j < CHAR_BIT; ++j) {
if (uc & MSB_MASK)
bits[j] = '1';
uc <<= 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);
printb('A');
printf("\n");
return 0;
}
输出
$ ./printb
11111111
11111111
00000000 11111111
00000000 00000000 00000000 11111111
01000100
00000000 00000000 00000000 01000100
01000100 00010001 11111111 00000001
00000000 01000011
00000000 00000000 00000000 01000001
我使用了另一种方法(bitprint.h)用所有字节(作为位字符串)填充一个表,并根据输入/索引字节打印它们。值得一看。
Use:
char buffer [33];
itoa(value, buffer, 2);
printf("\nbinary: %s\n", buffer);
有关更多参考,请参见如何通过printf打印二进制数。