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
You can use binary literals. They are standardized in C++14. For example,
int x = 0b11000;
Support in GCC began in GCC 4.3 (see https://gcc.gnu.org/gcc-4.3/changes.html) as extensions to the C language family (see https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions), but since GCC 4.9 it is now recognized as either a C++14 feature or an extension (see Difference between GCC binary literals and C++14 ones?)
Support in Visual Studio started in Visual Studio 2015 Preview (see https://www.visualstudio.com/news/vs2015-preview-vs#C++).
The C++ over-engineering mindset is already well accounted for in the other answers here. Here's my attempt at doing it with a C, keep-it-simple-ffs mindset:
unsigned char x = 0xF; // binary: 00001111
The smallest unit you can work with is a byte (which is of char
type). You can work with bits though by using bitwise operators.
As for integer literals, you can only work with decimal (base 10), octal (base 8) or hexadecimal (base 16) numbers. There are no binary (base 2) literals in C nor C++.
Octal numbers are prefixed with 0
and hexadecimal numbers are prefixed with 0x
. Decimal numbers have no prefix.
In C++0x you'll be able to do what you want by the way via user defined literals.
You can use BOOST_BINARY while waiting for C++0x. :) BOOST_BINARY
arguably has an advantage over template implementation insofar as it can be used in C programs as well (it is 100% preprocessor-driven.)
To do the converse (i.e. print out a number in binary form), you can use the non-portable itoa function, or implement your own.
Unfortunately you cannot do base 2 formatting with STL streams (since setbase will only honour bases 8, 10 and 16), but you can use either a std::string
version of itoa
, or (the more concise, yet marginally less efficient) 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;
}
produces:
hex: 0012, dec: 18, oct: 000022, bin: 10010
hex: 0012, dec: 18, oct: 000022, bin: 0000000000010010
Also read Herb Sutter's The String Formatters of Manor Farm for an interesting discussion.
A few compilers (usually the ones for microcontrollers) has a special feature implemented within recognizing literal binary numbers by prefix "0b..." preceding the number, although most compilers (C/C++ standards) don't have such feature and if it is the case, here it is my alternative solution:
#define B_0000 0
#define B_0001 1
#define B_0010 2
#define B_0011 3
#define B_0100 4
#define B_0101 5
#define B_0110 6
#define B_0111 7
#define B_1000 8
#define B_1001 9
#define B_1010 a
#define B_1011 b
#define B_1100 c
#define B_1101 d
#define B_1110 e
#define B_1111 f
#define _B2H(bits) B_##bits
#define B2H(bits) _B2H(bits)
#define _HEX(n) 0x##n
#define HEX(n) _HEX(n)
#define _CCAT(a,b) a##b
#define CCAT(a,b) _CCAT(a,b)
#define BYTE(a,b) HEX( CCAT(B2H(a),B2H(b)) )
#define WORD(a,b,c,d) HEX( CCAT(CCAT(B2H(a),B2H(b)),CCAT(B2H(c),B2H(d))) )
#define DWORD(a,b,c,d,e,f,g,h) HEX( CCAT(CCAT(CCAT(B2H(a),B2H(b)),CCAT(B2H(c),B2H(d))),CCAT(CCAT(B2H(e),B2H(f)),CCAT(B2H(g),B2H(h)))) )
// 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;
Disadvantages (it's not such a big ones):
Advantages:
spending processor time
in pointless operations (like "?.. :..", "<<", "+"
) to the executable program (it may be performed hundred of times in the final application);"mainly in C"
compilers and C++ as well (template+enum solution works only in C++ compilers
);"enum solution" (usually 255 = reach enum definition limit)
, differently, "literal constant" limitations, in the compiler allows greater numbers;several header files
(in most cases not easily readable and understandable, and make the project become unnecessarily confused and extended, like that using "BOOST_BINARY()"
);C++ provides a standard template named std::bitset
. Try it if you like.