Я могу использовать двоичный литерал в C или C++?

Я должен работать с двоичным числом.

Я пытался писать:

const x = 00010000;

Но это не работало.

Я знаю, что могу использовать шестнадцатеричное число, которое имеет то же значение как 00010000, но я хочу знать, существует ли тип в C++ для двоичных чисел и если нет, там другое решение для моей проблемы?

181
задан Peter Mortensen 12 September 2015 в 07:43
поделиться

10 ответов

Вы можете использовать BOOST_BINARY в ожидании C++0x. :) BOOST_BINARY, возможно, имеет преимущество перед шаблонной реализацией, поскольку может использоваться и в программах на C (она на 100% управляется препроцессором.)

Чтобы сделать обратное (т.е. вывести число в двоичной форме), вы можете использовать непортативную функцию itoa, или реализовать свою собственную.

К сожалению, вы не можете делать форматирование по основанию 2 с потоками STL (так как setbase будет уважать только основания 8, 10 и 16), но вы можете использовать либо std::string версию itoa, либо (более лаконичную, но немного менее эффективную) std::bitset.

#include <boost/utility/binary.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <bitset>
#include <iostream>
#include <iomanip>

using namespace std;

int main() {
  unsigned short b = BOOST_BINARY( 10010 );
  char buf[sizeof(b)*8+1];
  printf("hex: %04x, dec: %u, oct: %06o, bin: %16s\n", b, b, b, itoa(b, buf, 2));
  cout << setfill('0') <<
    "hex: " << hex << setw(4) << b << ", " <<
    "dec: " << dec << b << ", " <<
    "oct: " << oct << setw(6) << b << ", " <<
    "bin: " << bitset< 16 >(b) << endl;
  return 0;
}

производит:

hex: 0012, dec: 18, oct: 000022, bin:            10010
hex: 0012, dec: 18, oct: 000022, bin: 0000000000010010

Читайте также статью Херба Саттера The String Formatters of Manor Farm для интересного обсуждения.

70
ответ дан 23 November 2019 в 06:07
поделиться

Если вы используете GCC, вы можете использовать расширение GCC (которое включено в стандарт C ++ 14 ) для этого:

int x = 0b00010000;
258
ответ дан 23 November 2019 в 06:07
поделиться
template<unsigned long N>
struct bin {
    enum { value = (N%10)+2*bin<N/10>::value };
} ;

template<>
struct bin<0> {
    enum { value = 0 };
} ;

// ...
    std::cout << bin<1000>::value << '\n';

Самая левая цифра литерала по-прежнему должна быть 1, но тем не менее.

73
ответ дан 23 November 2019 в 06:07
поделиться

Вы можете использовать функцию, найденную в этом вопросе , чтобы получить до 22 бит в C ++. Вот код из ссылки, отредактированный соответствующим образом:

template< unsigned long long N >
struct binary
{
  enum { value = (N % 8) + 2 * binary< N / 8 > :: value } ;
};

template<>
struct binary< 0 >
{
  enum { value = 0 } ;
};

Таким образом, вы можете сделать что-то вроде binary <0101011011> :: value .

10
ответ дан 23 November 2019 в 06:07
поделиться

Как уже было отвечено, в стандартах языка C нет способа прямой записи двоичных чисел. Однако существуют расширения компилятора, и, по-видимому, C++14 включает префикс 0b для двоичных чисел. (Обратите внимание, что этот ответ был первоначально опубликован в 2010 году.)

Одним из популярных обходных путей является включение заголовочного файла с вспомогательными макросами. Одним из простых вариантов также является создание файла, включающего макроопределения для всех 8-битных шаблонов, например:

#define B00000000 0
#define B00000001 1
#define B00000010 2
…

В результате получается всего 256 #defines, а если требуются более крупные, чем 8-битные двоичные константы, эти определения могут быть объединены сдвигами и OR, возможно, с вспомогательными макросами (например, BIN16(B00000001,B00001010)). (Наличие отдельных макросов для каждого 16-битного, не говоря уже о 32-битных значениях, неправдоподобно).

Конечно, недостатком этого синтаксиса является то, что он требует записи всех ведущих нулей, но это также может сделать его более понятным для таких применений, как установка битовых флагов и содержимого аппаратных регистров. Функционально-подобный макрос, приводящий к синтаксису без этого свойства, приведен в bithacks.h по ссылке выше.

16
ответ дан 23 November 2019 в 06:07
поделиться

Наименьшей единицей, с которой вы можете работать, является байт (который имеет значение char типа). Вы можете работать с битами, используя побитовые операторы.

Что касается целочисленных литералов, вы можете работать только с десятичными (основание 10), восьмеричными (основание 8) или шестнадцатеричными (основание 16) числами. В C и C ++ нет двоичных (базовых 2) литералов.

Восьмеричные числа имеют префикс 0 , а шестнадцатеричные числа имеют префикс 0x . Десятичные числа не имеют префикса.

В C ++ 0x вы можете делать то, что хотите, с помощью пользовательских литералов .

7
ответ дан 23 November 2019 в 06:07
поделиться

C ++ предоставляет стандартный шаблон с именем std :: bitset . Попробуйте, если хотите.

-1
ответ дан 23 November 2019 в 06:07
поделиться

Эта ветка может помочь.

/* Helper macros */
#define HEX__(n) 0x##n##LU
#define B8__(x) ((x&0x0000000FLU)?1:0) \
+((x&0x000000F0LU)?2:0) \
+((x&0x00000F00LU)?4:0) \
+((x&0x0000F000LU)?8:0) \
+((x&0x000F0000LU)?16:0) \
+((x&0x00F00000LU)?32:0) \
+((x&0x0F000000LU)?64:0) \
+((x&0xF0000000LU)?128:0)

/* User macros */
#define B8(d) ((unsigned char)B8__(HEX__(d)))
#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \
+ B8(dlsb))
#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
+ ((unsigned long)B8(db2)<<16) \
+ ((unsigned long)B8(db3)<<8) \
+ B8(dlsb))


#include <stdio.h>

int main(void)
{
    // 261, evaluated at compile-time
    unsigned const number = B16(00000001,00000101);

    printf("%d \n", number);
    return 0;
}

Это работает! (Все кредиты принадлежат Тому Торфсу.)

20
ответ дан 23 November 2019 в 06:07
поделиться

«Тип» двоичного числа такой же, как и у любого десятичного, шестнадцатеричного или восьмеричного числа: int (или даже char, short, long long).

Когда вы назначаете константу, вы не можете присвоить ей 11011011 (любопытно и к сожалению), но вы можете использовать шестнадцатеричный. Hex немного легче мысленно перевести. Разделить на полубайты (4 бита) и преобразовать в символ в [0-9a-f].

2
ответ дан 23 November 2019 в 06:07
поделиться

C не имеет родной нотации для чистых двоичных чисел. Лучше всего выбрать восьмеричное (например, 07777 ) или шестнадцатеричное (например, 0xfff ).

12
ответ дан 23 November 2019 в 06:07
поделиться