C语言 用C代码编写二进制数系统

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15114140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:29:06  来源:igfitidea点击:

Writing binary number system in C code

c

提问by cipher

As we use 0xprefix for hexadecimal numbers, and 0for octal ones, is there anything that can be done for binary numbers?

正如我们0x对十六进制数和0八进制数使用前缀一样,对二进制数有什么可以做的吗?

I tried the bsuffix, but the GCCdidn't allow it.

我尝试了b后缀,但GCC不允许。

Error: invalid suffix "b" on integer constant

错误:整数常量上的后缀“b”无效

Is it possible?

是否可以?

回答by

Standard C doesn't define binary constants. There's a GNU (I believe) extension though (among popular compilers, clang adapts it as well): the 0bprefix:

标准 C 没有定义二进制常量。虽然有一个 GNU(我相信)扩展(在流行的编译器中,clang 也适应了它):0b前缀:

int foo = 0b1010;

If you want to stick with standard C, then there's an option: you can combine a macro and a function to create an almostreadable "binary constant" feature:

如果你想坚持使用标准 C,那么有一个选择:你可以结合一个宏和一个函数来创建一个几乎可读的“二进制常量”特性:

#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;
}

And then you can use it like this:

然后你可以像这样使用它:

int foo = B(1010);

If you turn on heavy compiler optimizations, the compiler will most likely eliminate the function call completely (constant folding) or will at least inline it, so this won't even be a performance issue.

如果您打开大量编译器优化,编译器很可能会完全消除函数调用(常量折叠)或至少将其内联,因此这甚至不会成为性能问题。

Proof:

证明:

The following code:

以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>


#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;
}

has been compiled using clang -o baz.S baz.c -Wall -O3 -S, and it produced the following assembly:

已使用 编译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    1, %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

So clangcompletely eliminated the call to the function, and replaced its return value with 101. Neat, huh?

因此clang完全消除了对函数的调用,并将其返回值替换为101. 整洁吧?

回答by bash.d

Prefix you literal with 0blike in

0blike in前缀你的文字

int i = 0b11111111;

See here.

这里

回答by Avidan Borisov

Use BOOST_BINARY(Yes, you can use it in C).

使用BOOST_BINARY(是的,您可以在 C 中使用它)。

#include <boost/utility/binary.hpp>
...
int bin = BOOST_BINARY(110101);

This macro is expanded to an octal literal during preprocessing.

此宏在预处理期间扩展为八进制文字。