Написание двоичной числовой системы в коде C
Поскольку мы используем префикс 0x
для шестнадцатеричных чисел и 0
для восьмеричных, есть ли что-нибудь, что можно сделать для двоичных чисел?
Я попробовал суффикс b
, но GCC этого не допустил.
Ошибка: недопустимый суффикс «b» на целочисленной константе
Является ли это возможным?
- Преобразование int в 4-байтовый массив символов (C)
- целочисленный размер в c зависит от того, что?
- Как преобразовать целое число в шестнадцатеричную строку в C?
- Где найти реализации функций stdio.h?
- Путаница вычитания указателя
- Возвращаемое значение оператора «==» в C
- Передача многомерных массивов в качестве аргументов функции в C
- Может ли sizeof (int) когда-либо быть 1 в размещенной реализации?
Стандарт C не определяет двоичные константы. Хотя есть расширение GNU (я считаю) (среди популярных компиляторов, clang также его адаптирует): префикс 0b
:
int foo = 0b1010;
Если вы хотите придерживаться стандартного 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; }
И тогда вы можете использовать его так:
int foo = B(1010);
Если вы включите мощную оптимизацию компилятора, компилятор, скорее всего, полностью отключит вызов функции (постоянная сворачивание) или, по крайней мере, встроит его, поэтому это даже не будет проблемой производительности.
Доказательство:
Следующий код:
#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);
Этот макрос расширяется до восьмеричного литерала во время предварительной обработки.