我需要处理一个二进制数。
我试着写:
const char x = 00010000;
但这并没有起作用。
我知道我可以使用与00010000值相同的十六进制数,但我想知道在c++中是否有用于二进制数的类型,如果没有,是否有其他解决方案?
我需要处理一个二进制数。
我试着写:
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》,了解有趣的讨论。
其他回答
你可以使用二进制字面值。它们是在c++ 14中标准化的。例如,
int x = 0b11000;
GCC中的支持
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中的支持开始于Visual Studio 2015预览版(参见https://www.visualstudio.com/news/vs2015-preview-vs#C++)。
您可以使用的最小单位是字节(char类型)。您可以使用位操作符来处理位。
至于整数字面值,您只能使用十进制(以10为基数)、八进制(以8为基数)或十六进制(以16为基数)数字。在C和c++中没有二进制(以2为基数)字面值。
八进制数前缀为0,十六进制数前缀为0x。十进制数没有前缀。
在c++ 0x中,你可以通过用户定义的文字来做你想做的事情。
这篇文章可能会有所帮助。
/* 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;
}
它的工作原理!(所有的功劳都归于汤姆·托夫斯。)
二进制常数将在C23中标准化。在撰写本文时,最新的C2x标准草案的6.4.4.1/4中提到了拟议的符号:
[…二进制常数由前缀0b或0b后跟一组数字0或1组成。
我提出我的解决方案:
#define B(x) \
((((x) >> 0) & 0x01) \
| (((x) >> 2) & 0x02) \
| (((x) >> 4) & 0x04) \
| (((x) >> 6) & 0x08) \
| (((x) >> 8) & 0x10) \
| (((x) >> 10) & 0x20) \
| (((x) >> 12) & 0x40) \
| (((x) >> 14) & 0x80))
const uint8 font6[] = {
B(00001110), //[00]
B(00010001),
B(00000001),
B(00000010),
B(00000100),
B(00000000),
B(00000100),
B(00000000),
我用这种方式定义了8位字体和图形,但也可以使用更宽的字体。宏B可以定义为生成0b格式,如果编译器支持的话。 操作:将二进制数解释为八进制,然后将位掩码并一起移位。中间值受到编译器可以处理的最大整数的限制,我猜64位应该可以。
它完全由编译器处理,不需要运行时代码。