我需要处理一个二进制数。

我试着写:

const char x = 00010000;

但这并没有起作用。

我知道我可以使用与00010000值相同的十六进制数,但我想知道在c++中是否有用于二进制数的类型,如果没有,是否有其他解决方案?


当前回答

您可以在等待c++ 0x时使用BOOST_BINARY。BOOST_BINARY可以说比模板实现更有优势,因为它也可以在C程序中使用(它是100%预处理器驱动的)。

要做相反的事情(即以二进制形式打印一个数字),您可以使用不可移植的itoa函数,或者实现自己的函数。

不幸的是,你不能对STL流进行2进制格式化(因为setbase只支持8、10和16进制),但你可以使用itoa的std::string版本,或者(更简洁,但效率略低)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

也可以阅读Herb Sutter的《The String Formatters of Manor Farm》,了解有趣的讨论。

其他回答

基于其他一些答案,但这个将拒绝具有非法二进制字面值的程序。前导0是可选的。

template<bool> struct BinaryLiteralDigit;

template<> struct BinaryLiteralDigit<true> {
    static bool const value = true;
};

template<unsigned long long int OCT, unsigned long long int HEX>
struct BinaryLiteral {
    enum {
        value = (BinaryLiteralDigit<(OCT%8 < 2)>::value && BinaryLiteralDigit<(HEX >= 0)>::value
            ? (OCT%8) + (BinaryLiteral<OCT/8, 0>::value << 1)
            : -1)
    };
};

template<>
struct BinaryLiteral<0, 0> {
    enum {
        value = 0
    };
};

#define BINARY_LITERAL(n) BinaryLiteral<0##n##LU, 0x##n##LU>::value

例子:

#define B BINARY_LITERAL

#define COMPILE_ERRORS 0

int main (int argc, char ** argv) {
    int _0s[] = { 0, B(0), B(00), B(000) };
    int _1s[] = { 1, B(1), B(01), B(001) };
    int _2s[] = { 2, B(10), B(010), B(0010) };
    int _3s[] = { 3, B(11), B(011), B(0011) };
    int _4s[] = { 4, B(100), B(0100), B(00100) };

    int neg8s[] = { -8, -B(1000) };

#if COMPILE_ERRORS
    int errors[] = { B(-1), B(2), B(9), B(1234567) };
#endif

    return 0;
}

你也可以像这样使用内联汇编:

int i;

__asm {
    mov eax, 00000000000000000000000000000000b
    mov i,   eax
}

std::cout << i;

好吧,这可能有点过分,但确实有效。

c++提供了一个名为std::bitset的标准模板。如果你喜欢,可以试试。

您可以使用的最小单位是字节(char类型)。您可以使用位操作符来处理位。

至于整数字面值,您只能使用十进制(以10为基数)、八进制(以8为基数)或十六进制(以16为基数)数字。在C和c++中没有二进制(以2为基数)字面值。

八进制数前缀为0,十六进制数前缀为0x。十进制数没有前缀。

在c++ 0x中,你可以通过用户定义的文字来做你想做的事情。

c++的过度工程思维已经在这里的其他答案中得到了很好的解释。以下是我尝试用C,保持简单的心态来做这件事:

unsigned char x = 0xF; // binary: 00001111