我需要使用二进制数.
我试着写:
const x = 00010000;
Run Code Online (Sandbox Code Playgroud)
但它没有用.
我知道我可以使用具有相同值的十六进制数字00010000
,但我想知道C++中是否存在二进制数的类型,如果没有,是否有另一种解决方案可以解决我的问题?
qrd*_*rdl 260
如果您正在使用GCC,那么您可以使用GCC扩展(包含在C++ 14标准中):
int x = 0b00010000;
Run Code Online (Sandbox Code Playgroud)
Muh*_*eeb 86
您可以使用二进制文字.它们在C++ 14中标准化.例如,
int x = 0b11000;
Run Code Online (Sandbox Code Playgroud)
GCC中的支持始于GCC 4.3(请参阅https://gcc.gnu.org/gcc-4.3/changes.html)作为C语言系列的扩展(请参阅https://gcc.gnu.org/onlinedocs/gcc/ C-Extensions.html#C-Extensions),但是从GCC 4.9开始,它现在被认为是C++ 14特性或扩展(参见GCC二进制文字和C++ 14之间的区别?)
Visual Studio中的支持在Visual Studio 2015 Preview中启动(请参阅https://www.visualstudio.com/news/vs2015-preview-vs#C++).
wil*_*ell 73
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';
Run Code Online (Sandbox Code Playgroud)
文字的最左边数字仍然必须是1,但仍然是.
vla*_*adr 70
您可以使用BOOST_BINARY
在等待的C++ 0x.:) BOOST_BINARY
可以说比模板实现有优势,因为它也可以在C程序中使用(它是100%预处理器驱动的.)
要进行相反(即以二进制形式打印数字),您可以使用非便携式itoa
功能,或实现自己的功能.
不幸的是,你不能做基地2 STL格式数据流(因为setbase
只兑现基地8,10和16),但你可以使用一个std::string
版本的itoa
,或者(更简洁,但稍微低效率)std::bitset
.
(谢谢你罗杰的BOOST_BINARY
提示!)
#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;
}
Run Code Online (Sandbox Code Playgroud)
生产:
hex: 0012, dec: 18, oct: 000022, bin: 10010
hex: 0012, dec: 18, oct: 000022, bin: 0000000000010010
Run Code Online (Sandbox Code Playgroud)
另请阅读Herb Sutter的The Manor Formatters of Manor Farm进行有趣的讨论.
小智 30
一些编译器(通常是微控制器的编译器)具有一个特殊功能,通过前缀"0b ..."识别文字二进制数,虽然大多数编译器(C/C++标准)没有这样的功能,如果它是这样,这是我的替代解决方案:
#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;
Run Code Online (Sandbox Code Playgroud)
缺点(它不是那么大):
优点:
spending processor time
无意义操作(like "?.. :..", "<<", "+"
)(在最终应用程序中可能执行了数百次);"mainly in C"
编译器和C++(template+enum solution works only in C++ compilers
);"enum solution" (usually 255 = reach enum definition limit)
不同的"文字常量"限制来表示常量值,那么就会有早期的长度限制(通常是8位:0-255),在编译器中允许更大的数字;several header files
(在大多数情况下不易读取和理解,并使项目变得不必要地混淆和扩展,如使用"BOOST_BINARY()"
);Fed*_*oni 20
这个帖子可能有帮助.
/* 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;
}
Run Code Online (Sandbox Code Playgroud)
有用!(所有学分都归Tom Torfs所有.)
Ark*_*kku 16
如前所述,C标准无法直接写入二进制数.但是,有编译器扩展,显然C++ 14包含0b
二进制的前缀.(请注意,此答案最初发布于2010年.)
一种流行的解决方法是包含带辅助宏的头文件.一个简单的选择是生成一个包含所有8位模式的宏定义的文件,例如:
#define B00000000 0
#define B00000001 1
#define B00000010 2
…
Run Code Online (Sandbox Code Playgroud)
这导致仅256 #define
秒,并且如果需要大于8位二进制常量,则这些定义可以与移位和OR组合,可能与辅助宏(例如,BIN16(B00000001,B00001010)
)一起.(每个16位具有单独的宏,更不用说32位值,这是不可信的.)
当然,缺点是这种语法需要写入所有前导零,但这也可以使其更清晰地用于设置位标志和硬件寄存器的内容.对于类似函数的宏,导致语法没有此属性,请参阅bithacks.h
上面的链接.
小智 15
在这里的其他答案中已经充分考虑了C++过度工程的思维方式.这是我尝试使用C,keep-it-simple-ffs心态来做到这一点:
unsigned char x = 0xF; // binary: 00001111
Run Code Online (Sandbox Code Playgroud)
Mar*_*som 10
您可以使用此问题中的函数在C++中获得最多22位.这是链接中的代码,经过适当编辑:
template< unsigned long long N >
struct binary
{
enum { value = (N % 8) + 2 * binary< N / 8 > :: value } ;
};
template<>
struct binary< 0 >
{
enum { value = 0 } ;
};
Run Code Online (Sandbox Code Playgroud)
所以你可以做点什么binary<0101011011>::value
.
您可以使用的最小单位是一个字节(char
类型).您可以通过使用按位运算符来处理位.
对于整数文字,您只能使用十进制(基数10),八进制(基数8)或十六进制(基数16)数字.C和C++中没有二进制(基数2)文字.
八进制数字以前缀为前缀,0
十六进制数字以前缀为前缀0x
.十进制数字没有前缀.
在C++ 0x中,您将能够通过用户定义的文字来执行您想要的操作.
基于其他一些答案,但这个答案将拒绝具有非法二进制文字的程序。前导零是可选的。
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
Run Code Online (Sandbox Code Playgroud)
例子:
#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;
}
Run Code Online (Sandbox Code Playgroud)
您还可以像这样使用内联汇编:
int i;
__asm {
mov eax, 00000000000000000000000000000000b
mov i, eax
}
std::cout << i;
Run Code Online (Sandbox Code Playgroud)
好吧,这可能有点矫枉过正,但它确实有效。
归档时间: |
|
查看次数: |
341389 次 |
最近记录: |