最稳妥用std::bitset,需显式指定宽度(如std::bitset(x).to_string()),负数按补码存储;c++20可用std::format("{:b}", x),但兼容性差;itoa非标准,应避免。

用 std::bitset 最稳妥,但要注意类型宽度
直接转二进制字符串,std::bitset 是标准库里最省心的选择,不用手动位运算、不依赖编译器扩展。但它要求编译时知道整数位宽——比如 int 通常是 32 位,但标准没规定,所以不能写 std::bitset<sizeof></sizeof>(sizeof 不是常量表达式)。
- 安全写法是显式指定宽度:
std::bitset(x),再调用.to_string() - 如果
x是负数,std::bitset按补码存,结果就是你看到的二进制表示(比如std::bitset(-1)得到"11111111") - 别用
std::bitset<sizeof></sizeof>——sizeof返回的是size_t,不是模板非类型参数允许的常量表达式,编译不过
手写循环位移容易漏掉高位或符号位
自己写循环右移再取 & 1 看似直观,但有三个常见翻车点:没处理负数、没考虑 int 可能是 32 或 64 位、循环次数写死成 32 却在 64 位系统上截断。
- 用
static_cast<unsigned int></unsigned>转一下再移,避免右移负数时行为未定义 - 循环次数建议用
sizeof(int) * 8,但必须确保变量是已知类型的(比如unsigned int),否则sizeof可能返回意外值 - 从高位开始拼字符串更自然(避免最后 reverse),但得注意:先移
31位再& 1,而不是从 0 开始
std::format(C++20)简洁但兼容性差
C++20 引入了 std::format,写起来最干净:std::format("{:b}", x) 直接出二进制字符串。但它目前只被较新编译器支持(GCC 13+、Clang 15+、MSVC 19.32+),且 libc++ 和 libstdc++ 实现进度不一。
- 如果你项目已强制 C++20 且控制编译环境,这是首选
- 否则别用——
std::format在旧标准下根本不可用,连头文件都找不到 - 它对负数默认输出带符号(如
-101),不像bitset那样给补码,要补码就得自己转无符号再格式化
别用 itoa:它不是标准函数
很多老代码里出现 itoa(x, buf, 2),看着方便,但它根本不在 C++ 标准里,是某些 C 库(如 MSVC CRT、glibc 的非标准扩展)提供的。跨平台一编译就报错:'itoa' was not declared in this scope。
立即学习“C++免费学习笔记(深入)”;
- Linux 下通常没有
itoa,得自己实现或换std::stringstream(性能差) - 就算有,
itoa第二个参数是char*,容易缓冲区溢出——int最多要 33 字符(32 位 + 符号位),忘了留结尾\0就 UB - 替代方案明确:用
std::bitset或 C++20 的std::format,别碰这个非标函数
真正麻烦的从来不是“怎么转”,而是“转出来是不是你想要的二进制”——补码?原码?要不要前导零?有没有符号?这些细节不提前想清楚,后面调试花的时间远超写几行代码。









