Is there a printf converter to print in binary format?
我可以用printf打印十六进制或八进制数字。是否有格式标记以二进制或任意基打印?
我在管理GCC。
1 2 3 4 5 6 |
黑客,但对我有用:
1 2 3 4 5 6 7 8 9 10 | #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') |
。
1 |
对于多字节类型
1 2 3 | printf("m:"BYTE_TO_BINARY_PATTERN""BYTE_TO_BINARY_PATTERN" ", BYTE_TO_BINARY(m>>8), BYTE_TO_BINARY(m)); |
。
不幸的是,你需要所有额外的报价。这种方法具有宏的效率风险(不将函数作为参数传递给
打印任何数据类型的二进制文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
。
测试
1 2 3 4 5 6 7 8 9 10 | 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; } |
号
这里有一个快速的黑客演示技术做你想做的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #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 ", strtol(b, &tmp, 2)); } { /* byte to binary string */ printf("%s ", byte_to_binary(5)); } return 0; } |
glibc中通常没有二进制转换说明符。
可以向glibc中的printf()函数系列添加自定义转换类型。有关详细信息,请参阅a href="http://www.gnu.org/software/libc/manual/html_node/customizing-printf.html"rel="noreferrer">注册/a a。如果自定义的%b转换简化了应用程序代码使其可用,则可以添加该转换以供自己使用。
下面是一个如何在glibc中实现自定义printf格式的示例。
你可以用一个小桌子来提高速度1。类似的技术在嵌入式世界中很有用,例如,要反转一个字节:
1 2 3 4 5 6 7 8 9 10 11 | 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我主要指的是嵌入式应用程序,其中优化器没有那么激进,速度差异是可见的。
打印最低有效位并将其右移。这样做,直到整数变为零,以相反的顺序打印不带前导零的二进制表示。使用递归,可以很容易地纠正顺序。
1 2 3 4 5 6 7 8 9 | #include <stdio.h> void print_binary(int number) { if (number) { print_binary(number >> 1); putc((number & 1) ? '1' : '0', stdout); } } |
号
对我来说,这是解决这个问题最干净的方法之一。如果您喜欢
在线演示
根据@william whyte的回答,这是一个宏,它提供
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* --- 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" ", PRINTF_BYTE_TO_BINARY_INT64(flag)); return 0; } |
号
此输出:
1 | My Flag 0001011011100001001010110111110101111000100100001111000000101000 |
号
为了便于阅读,您可能需要添加分隔符,例如:
1 | My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000 |
号
以下是函数的一个版本,它不受可重入性问题或参数大小/类型限制的影响:
1 2 3 4 5 6 7 8 9 | #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; } |
号
请注意,如果您只是将2替换为所需的基,那么对于2到10之间的任何基,此代码都可以正常工作。用法是:
1 2 3 |
号
其中,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } |
有些运行时支持"%b",尽管这不是标准。
有关有趣的讨论,请参见此处:
http://bytes.com/forum/thread591027.html
高温高压
之前发布的答案都不是我想要的,所以我写了一个。在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* * 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," "); // 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 ", 65); return (EXIT_SUCCESS); } |
此代码应能处理多达64位的需求。我创建了两个函数pbin&pbinfill。两者都做相同的事情,但是pbinfill用fillchar填充前导空格。测试函数生成一些测试数据,然后使用该函数打印出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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; } |
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | void test() { char so[kDisplayWidth+1]; // working buffer for pBin long int val=1; do { printf("%ld =\t\t%#lx =\t\t0b%s ",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 |
。
C标准库中没有格式化函数来输出这样的二进制文件。printf系列支持的所有格式操作都是面向人类可读的文本的。
也许有点OT,但是如果您只需要它来进行调试,以理解或重新跟踪您正在执行的一些二进制操作,那么您可以查看wcalc(一个简单的控制台计算器)。使用-b选项可以获得二进制输出。
例如
1 2 | $ wcalc -b"(256 | 3) & 0xff" = 0b11 |
号
Is there a printf converter to print in binary format?
号
在任何基础上打印[2-36]
到目前为止,所有其他答案都至少有一个局限性。
对返回缓冲区使用静态内存。这限制了函数用作
将需要调用代码的内存分配给空闲指针。
要求调用代码显式提供适当的缓冲区。
直接呼叫
使用缩小的整数范围。
以下内容不受上述限制。它需要C99或更高版本,并使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include #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]){" <hr><P>以下递归函数可能有用:</P>[cc lang="c"]void bin(int n) { /* Step 1 */ if (n > 1) bin(n/2); /* Step 2 */ printf("%d", n % 2); } |
号
我优化了大小和c++的顶部解决方案,并得到了这个解决方案:
1 2 3 4 5 6 7 8 9 10 11 | 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; } |
号
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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'); } } |
号
我的解决方案:
1 2 3 4 5 6 7 8 9 10 |
。
使用更少的代码和资源从任何类型打印位
这种方法具有以下特性:
- 使用变量和文本。
- 不需要时不重复所有位。
- 仅当完成一个字节时才调用printf(并非所有位都不必要)。
- 适用于任何类型。
- 使用小的和大的endianness(使用gcc定义进行检查)。
- 使用的typeof()不是C标准,但主要是定义的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #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(" "); } 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(" "); return 0; } |
产量
1 2 3 4 5 6 7 8 9 | $ ./printb 11111111 11111111 00000000 11111111 00000000 00000000 00000000 11111111 01000100 00000000 00000000 00000000 01000100 01000100 00010001 11111111 00000001 00000000 01000011 |
。
我使用了另一种方法(bit print.h)用所有字节(作为位字符串)填充一个表,并根据输入/索引字节打印它们。值得一看。
我喜欢paniq编写的代码,静态缓冲区是个好主意。但是,如果希望在一个printf()中使用多个二进制格式,则会失败,因为它总是返回相同的指针并覆盖数组。
这里有一个C样式的下拉框,用于在拆分缓冲区上旋转指针。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } |
根据@ideasman42在回答中的建议,这是一个宏,它提供了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* --- 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" ", PRINTF_BYTE_TO_BINARY_INT64(flag)); return 0; } |
。
此输出:
1 | My Flag 0001011011100001001010110111110101111000100100001111000000101000 |
为了可读性,您可以将:
这将输出:
1 | My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000 |
。
或
1 | My Flag 00010110 11100001 00101011 01111101 01111000 10010000 11110000 00101000 |
号
没有标准的便携方式。
有些实现提供了ITOA(),但它不会出现在大多数情况下,而且它有一个有点糟糕的接口。但是代码在链接后面,应该可以让您非常容易地实现自己的格式化程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* 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" */ |
号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
号
接下来将向您显示内存布局:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #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; } |
号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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); } } |
应该工作-未经测试。
用途:
。
有关更多参考,请参阅如何通过printf打印二进制数。
快速简便的解决方案:
1 2 3 4 5 |
号
适用于任何大小的类型和有符号和无符号整数。需要"&1"来处理已签名的int,因为移位可能会进行符号扩展。
有很多方法可以做到这一点。这是一个非常简单的方法,可以从有符号或无符号的32位类型中打印32位或n位(如果有符号,不加负号,只打印实际位),并且不返回回车。请注意,i在位移位之前是递减的:
1 2 | #define printbits_n(x,n) for (int i=n;i;i--,putchar('0'|(x>>i)&1)) #define printbits_32(x) printbits_n(x,32) |
号
返回一个包含位的字符串以后存储或打印怎么样?您可以分配内存并返回它,用户必须释放它,或者返回静态字符串,但是如果再次调用它,或者被另一个线程调用,它将被击倒。两种方法都显示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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; } |
号
呼叫方式:
1 2 3 4 5 6 7 8 9 10 | // memory allocated string returned which needs to be freed char *pstr = int_to_bitstring_alloc(0x97e50ae6, 17); printf("bits = 0b%s ", 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 ", pstr2); |
我只想发布我的解决方案。它用于获取一个字节的零和一个字节的零,但是很少调用这个函数可以用于更大的数据块。我将它用于128位或更大的结构。您还可以将其修改为使用大小作为输入参数和指向要打印的数据的指针,这样它就可以独立于大小。但对我来说,它是有效的,所以退出。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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); } |
号
以下是paniq解决方案的一个小变化,它使用模板来允许打印32位和64位整数:
1 2 3 4 5 6 7 8 9 10 | 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); } |
可以像这样使用:
1 2 3 4 5 6 7 |
。
结果如下:
1 2 | 0x1e127ad: 00000001111000010010011110101101 0x2e0b04ce0: 0000000000000000000000000000001011100000101100000100110011100000 |
。
我是这样做的
1 2 3 4 | 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 ); } |
号
在C语言中的一个小的实用函数,在解决一个位操作问题时可以做到这一点。这将使用一个掩码(1)检查每个设置位的字符串<
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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(" "); while (i>=0) { if (*temp & (1 << i)) { printf("1"); } else { printf("0"); } i--; } temp = temp+1; i = 7; printf(" "); } } |
号
使用标准库将任何整型的一个语句泛型转换为二进制字符串表示:
1 2 3 4 5 6 7 | #include <bitset> MyIntegralType num = 10; print("%s ", std::bitset<sizeof(num) * 8>(num).to_string().insert(0,"0b").c_str() ); // prints"0b1010 " |
或者只是:
另一种用二进制打印的方法是:首先转换整数。
要以二进制方式打印
绕过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #include <stdint.h> #include <stdio.h> #include <inttypes.h> 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 ", char_to_bin10(0xF1)); // 11110001 printf("%" PRIX64" ", uint16_to_bin16(0xF731)); // 1111011100110001 } |
。
还有一种想法是将数字转换为十六进制格式,然后将每个十六进制密码解码为四个"位"(1和0)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | const char* binary(int n) { static const char binnums[16][5] = {"0000","0001","0010","0011", "0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111" }; static const char* hexnums ="0123456789abcdef"; static char inbuffer[16], outbuffer[4*16]; const char *i; sprintf(inbuffer,"%x",n); // hexadecimal n -> inbuffer for(i=inbuffer; *i!=0; ++i) { // for each hexadecimal cipher int d = strchr(hexnums,*i) - hexnums; // store its decimal value to d char* o = outbuffer+(i-inbuffer)*4; // shift four characters in outbuffer sprintf(o,"%s",binnums[d]); // place binary value of d there } return strchr(outbuffer,'1'); // omit leading zeros } puts(binary(42)); // outputs 101010 |
。
也许有人会发现这个解决方案很有用:
1 2 3 4 5 6 | 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'); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
号
1 2 3 4 5 6 7 | void DisplayBinary(unsigned int n) { int l = sizeof(n) * 8; for (int i = l - 1 ; i >= 0; i--) { printf("%x", (n & (1 << i)) >> i); } } |
号
即使对于支持%b的运行库,它似乎也只适用于整数值。
如果你想打印二进制的浮点值,我写了一些代码,你可以在http://www.exploringbinary.com/converting-floating-point-numbers-to-binary-strings-in-c/上找到。
1 2 3 4 5 6 7 8 9 10 11 12 | 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 */ } |
号
调用函数"拥有"字符串…
1 2 3 4 5 | char BinaryString[17]; ... PrintBinary( Value, 16, BinaryString); printf("yadda yadda %s yadda... ", BinaryString); |
号
根据CPU的不同,printBinary中的大多数操作都呈现为一个或极少数的机器指令。
是否有以二进制格式打印的printf转换器?
没有标准的printf格式说明符来完成"二进制"输出。这是我在需要时设计的替代方案。
矿山为2到36之间的任何基地施工。它将这些数字扇出到递归调用的调用帧中,直到达到比基值小的数字为止。然后它向后"遍历",向前填充缓冲区,然后返回。返回值是使用的大小,如果缓冲区不够大,无法容纳字符串,则返回-1。
1 2 3 4 5 6 7 8 9 10 | int conv_rad (int num, int rad, char *s, int n) { char *vec ="0123456789""ABCDEFGHIJKLM""NOPQRSTUVWXYZ"; int off; if (n == 0) return 0; if (num < rad) { *s = vec[num]; return 1; } off = conv_rad(num/rad, rad, s, n); if ((off == n) || (off == -1)) return -1; s[off] = vec[num%rad]; return off+1; } |
号
一个重要的警告:这个函数是为与"pascal"样式的字符串一起使用而设计的,这些字符串的长度都是环绕的。因此,写入的
下面是一个非常简单的例子:
1 2 3 4 5 6 7 8 9 |
。
1 2 3 4 5 6 7 8 |
号
The following function returns binary representation of given unsigned integer using pointer arithmetic without leading zeros:
1 2 3 4 5 6 7 8 9 | const char* toBinaryString(unsigned long num) { static char buffer[CHAR_BIT*sizeof(num)+1]; char* pBuffer = &buffer[sizeof(buffer)-1]; do *--pBuffer = '0' + (num & 1); while (num >>= 1); return pBuffer; } |
请注意,不需要显式设置
通过简单地修改
下面是一个示例用法:
1 2 3 4 5 6 7 8 |
号
其期望输出为:
1 2 | >>> 1<<< >>>11111110 <<< |
使用以下功能:
1 2 3 4 5 6 7 8 9 10 11 12 |
号
这可能不是很有效,但很简单。试试这个:
1 2 3 4 5 6 7 8 9 |
执行一个函数并调用它
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | display_binary(int n) { long int arr[32]; int arr_counter=0; while(n>=1) { arr[arr_counter++]=n%2; n/=2; } for(int i=arr_counter-1;i>=0;i--) { printf("%d",arr[i]); } } |
号