標題: C++ 的二进制语法与语义 [打印本頁] 作者: 妖刀路过 時間: 2014-7-18 20:44 標題: C++ 的二进制语法与语义 二进制的语法 C/C++ 默认数字使用十进制,八进制使用前缀 0, 十六进制使用前缀 0x 或 0X,二进制常数的提议被否决(引用 C 语言程序原理国际标准 的 6.4.4.1 章节字段 "A proposal to add binary constants was rejected due to lack of precedent and insufficient utility."),一直没有二进制的表示方法, GCC 使用 0b/0B 前缀作为扩展,其实很多编译器都有这个扩展的,只是标准委员会一直没采纳。直到 C++14 才引进,可谓姗姗来迟啊。这种二进制语义 Java 7 也早些时候引入,Python 2.6 以及后来的 3 也引入,Python 为了避免十进制与八进制的混淆,一律用字母前缀,不分大小写,0b 为二进制,0o 为八进制,ox 为十六进制。Python2 升到 Python3 时果断丢弃了原来的八进制语义(也就是在 C/C++/Java 里面有 0 前缀的八进制的语义)。
表示方法
1. 下面每行语句表达语义相同,只是选用不同的进制数表示。
int i = 0b101010; // binaryint i = 052; // octalint i = 42; // decimalint i = 0x2a; // hexadecimal
2. 使用 strtol/strtoll/strtoq 函数,可以将一个字符串转换成整数,base 取 2 表示转换成二进制数。
#include <stdlib.h>
long int strtol(const char *nptr, char **endptr, int base);
long long intstrtoll(const char *nptr, char **endptr, int base);
4. 可以使用 boost 库的 BOOST_BINARY, 可以每隔开几个数字一写,在表示很大的数时很方便阅读。
int value1 = BOOST_BINARY( 100 111000 01 1 110 );unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned longlong long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported
5. 如果不是一项工程,而是简短的程序,可以利用 C++ 的模板模拟二进制语义。
[url=][/url]
template<unsigned long long N>struct binary{ enum { value = (N%10) + binary<N/10>::value*2 };};template<>struct binary{ enum { value = 0 };}[url=][/url]
int value = static_cast<int>(binary<101010>::value);
上面的代码中, enum 是为了让变量在编译期获取结果,没有用整型。还有一个问题是如果数的开头有 0,结果可不妙。整个数被当成了八进制而不是十进制数解析,很容易滋生 bug。比较好的解决方法是数字经常以 0 开头(或添加断言强制),将十进制换成八进制。
[url=][/url]
// need to enable C++11 flagtemplate<unsigned long long>struct binary{ constexpr static int value = binary<N/8>::value + N%8;}; template<>struct binary<0>{ constexpr static int value = 0;}[url=][/url]