Can I use a binary literal in C or C++?

前端 未结 19 2435
梦如初夏
梦如初夏 2020-11-22 07:40

I need to work with a binary number.

I tried writing:

const x = 00010000;

But it didn\'t work.

I know that I can use an hex

相关标签:
19条回答
  • 2020-11-22 07:57

    Based on some other answers, but this one will reject programs with illegal binary literals. Leading zeroes are optional.

    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
    

    Example:

    #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;
    }
    
    0 讨论(0)
  • 2020-11-22 07:58

    C does not have native notation for pure binary numbers. Your best bet here would be either octal (e.g. 07777) of hexadecimal (e.g. 0xfff).

    0 讨论(0)
  • 2020-11-22 08:00

    I extended the good answer given by @renato-chandelier by ensuring the support of:

    • _NIBBLE_(…) – 4 bits, 1 nibble as argument
    • _BYTE_(…) – 8 bits, 2 nibbles as arguments
    • _SLAB_(…) – 12 bits, 3 nibbles as arguments
    • _WORD_(…) – 16 bits, 4 nibbles as arguments
    • _QUINTIBBLE_(…) – 20 bits, 5 nibbles as arguments
    • _DSLAB_(…) – 24 bits, 6 nibbles as arguments
    • _SEPTIBBLE_(…) – 28 bits, 7 nibbles as arguments
    • _DWORD_(…) – 32 bits, 8 nibbles as arguments

    I am actually not so sure about the terms “quintibble” and “septibble”. If anyone knows any alternative please let me know.

    Here is the macro rewritten:

    #define __CAT__(A, B) A##B
    #define _CAT_(A, B) __CAT__(A, B)
    
    #define __HEX_0000 0
    #define __HEX_0001 1
    #define __HEX_0010 2
    #define __HEX_0011 3
    #define __HEX_0100 4
    #define __HEX_0101 5
    #define __HEX_0110 6
    #define __HEX_0111 7
    #define __HEX_1000 8
    #define __HEX_1001 9
    #define __HEX_1010 a
    #define __HEX_1011 b
    #define __HEX_1100 c
    #define __HEX_1101 d
    #define __HEX_1110 e
    #define __HEX_1111 f
    
    #define _NIBBLE_(N1) _CAT_(0x, _CAT_(__HEX_, N1))
    #define _BYTE_(N1, N2) _CAT_(_NIBBLE_(N1), _CAT_(__HEX_, N2))
    #define _SLAB_(N1, N2, N3) _CAT_(_BYTE_(N1, N2), _CAT_(__HEX_, N3))
    #define _WORD_(N1, N2, N3, N4) _CAT_(_SLAB_(N1, N2, N3), _CAT_(__HEX_, N4))
    #define _QUINTIBBLE_(N1, N2, N3, N4, N5) _CAT_(_WORD_(N1, N2, N3, N4), _CAT_(__HEX_, N5))
    #define _DSLAB_(N1, N2, N3, N4, N5, N6) _CAT_(_QUINTIBBLE_(N1, N2, N3, N4, N5), _CAT_(__HEX_, N6))
    #define _SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7) _CAT_(_DSLAB_(N1, N2, N3, N4, N5, N6), _CAT_(__HEX_, N7))
    #define _DWORD_(N1, N2, N3, N4, N5, N6, N7, N8) _CAT_(_SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7), _CAT_(__HEX_, N8))
    

    And here is Renato's using example:

    char b = _BYTE_(0100, 0001); /* equivalent to b = 65; or b = 'A'; or b = 0x41; */
    unsigned int w = _WORD_(1101, 1111, 0100, 0011); /* equivalent to w = 57155; or w = 0xdf43; */
    unsigned long int dw = _DWORD_(1101, 1111, 0100, 0011, 1111, 1101, 0010, 1000); /* Equivalent to dw = 3745774888; or dw = 0xdf43fd28; */
    
    0 讨论(0)
  • 2020-11-22 08:02

    You can use a bitset

    bitset<8> b(string("00010000"));
    int i = (int)(bs.to_ulong());
    cout<<i;
    
    0 讨论(0)
  • 2020-11-22 08:03

    You could try using an array of bool:

    bool i[8] = {0,0,1,1,0,1,0,1}
    
    0 讨论(0)
  • 2020-11-22 08:04

    As already answered, the C standards have no way to directly write binary numbers. There are compiler extensions, however, and apparently C++14 includes the 0b prefix for binary. (Note that this answer was originally posted in 2010.)

    One popular workaround is to include a header file with helper macros. One easy option is also to generate a file that includes macro definitions for all 8-bit patterns, e.g.:

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

    This results in only 256 #defines, and if larger than 8-bit binary constants are needed, these definitions can be combined with shifts and ORs, possibly with helper macros (e.g., BIN16(B00000001,B00001010)). (Having individual macros for every 16-bit, let alone 32-bit, value is not plausible.)

    Of course the downside is that this syntax requires writing all the leading zeroes, but this may also make it clearer for uses like setting bit flags and contents of hardware registers. For a function-like macro resulting in a syntax without this property, see bithacks.h linked above.

    0 讨论(0)
提交回复
热议问题