用C代码编写二进制数系统
因为我们对hex数字使用0x
前缀,对于八进制数字使用0
,所以对二进制数字有什么可以做的吗?
我尝试了b
后缀,但GCC不允许。
错误:整数常量上的后缀“b”无效
可能吗?
标准C不定义二进制常量。 虽然有一个GNU(我相信)扩展(在流行的编译器中,clang也适应它): 0b
前缀:
int foo = 0b1010;
如果你想坚持标准C,那么有一个选项:你可以结合一个宏和一个函数来创建一个几乎可读的“二进制常量”function:
#define B(x) S_to_binary_(#x) static inline unsigned long long S_to_binary_(const char *s) { unsigned long long i = 0; while (*s) { i <<= 1; i += *s++ - '0'; } return i; }
然后你可以像这样使用它:
int foo = B(1010);
如果你打开繁重的编译器优化,编译器很可能完全消除函数调用(常量折叠)或至少内联它,所以这甚至不会成为性能问题。
certificate:
以下代码:
#include #include #include #include #define B(x) S_to_binary_(#x) static inline unsigned long long S_to_binary_(const char *s) { unsigned long long i = 0; while (*s) { i <<= 1; i += *s++ - '0'; } return i; } int main() { int foo = B(001100101); printf("%d\n", foo); return 0; }
已经使用clang -o baz.S baz.c -Wall -O3 -S
编译,它产生了以下程序集:
.section __TEXT,__text,regular,pure_instructions .globl _main .align 4, 0x90 _main: ## @main .cfi_startproc ## BB#0: pushq %rbp Ltmp2: .cfi_def_cfa_offset 16 Ltmp3: .cfi_offset %rbp, -16 movq %rsp, %rbp Ltmp4: .cfi_def_cfa_register %rbp leaq L_.str1(%rip), %rdi movl $101, %esi ## <= This line! xorb %al, %al callq _printf xorl %eax, %eax popq %rbp ret .cfi_endproc .section __TEXT,__cstring,cstring_literals L_.str1: ## @.str1 .asciz "%d\n" .subsections_via_symbols
所以clang
完全取消了对函数的调用,并将其返回值替换为101
。 整洁,对吧?
使用0b
作为文字前缀
int i = 0b11111111;
看到这里 。
使用BOOST_BINARY (是的,您可以在C中使用它)。
#include ... int bin = BOOST_BINARY(110101);
在预处理期间,此宏将扩展为八进制文字。