C++怎么实现十进制转二进制_C++位运算转换技巧【方法】

1次阅读

std::bitset 最快最安全但仅适用于编译期已知位宽;它无动态内存、截断风险小、支持 to_string(),但模板参数须为常量表达式,负数按补码处理,超范围会静默截断。

C++ 怎么实现十进制转二进制_C++ 位运算转换技巧【方法】

std::bitset 最快最安全,但只适用于编译期已知位宽的整数

直接把十进制整数转成二进制字符串显示,std::bitset 是最省心的选择——它不涉及动态内存、无符号截断风险小、输出可直接用 to_string()

但注意:模板参数必须是常量表达式,比如 std::bitsetstd::bitset,不能写 std::bitset<n></n>(n 是变量)。

  • 适用于 intunsigned int 等能隐式转换为对应位宽整型的值,超范围会静默截断(如 std::bitset(257) 得到 "00000001"
  • 负数会被按补码解释(std::bitset(-1)"11111111"),不是你想看的“-11111111”这种带符号表示
  • 如果只要打印、不存字符串,用 cout (x) 更轻量

示例:

int x = 13;<br>std::cout << std::bitset<8>(x) << "n"; // 输出 00001101

手写循环除 2 取余,兼容任意大小和符号,但要自己处理负号和逆序

这是最通用的办法,不依赖模板、不限位宽、能明确控制格式(比如要不要前导零、是否加“0b”前缀、负数怎么表示)。

立即学习 C++ 免费学习笔记(深入)”;

核心逻辑就三步:取绝对值 → 模 2 记余 → 商整除 2,直到商为 0;最后把余数序列倒过来。

  • 不处理负数时,-5 会变成 "101" 而非 "-101",得额外判断原值符号
  • 结果是字符串,每次 push_back 后要 reverse,别忘了
  • 输入为 0 时循环不进,必须单独返回 "0",否则结果为空

示例:

std::string dec2bin(int n) {<br>    if (n == 0) return "0";<br>    bool neg = n < 0;<br>    unsigned int u = neg ? -n : n;<br>    std::string s;<br>    while (u) {<br>        s.push_back('0' + (u & 1));<br>        u >>= 1;<br>    }<br>    std::reverse(s.begin(), s.end());<br>    return neg ? "-" + s : s;<br>}

std::format(C++20)能一行搞定,但 MSVC 早期版本不支持,Clang 需开启 -std=c++20

如果你用的是较新工具链,std::format("{:b}", x) 是最简洁的方案,自动处理符号、无截断、支持 long long,还能加宽度、填充等格式控制。

但它不是万能的:GCC 12+、Clang 14+、MSVC 19.30+ 才稳定支持;老版本编译直接报错 ‘format’is not a member of‘std’

  • {:b} 对负数输出补码形式(如 std::format("{:b}", -1) 在 32 位系统上是 32 个 1)
  • 想输出带符号的十进制风格(如 "-101"),得自己判断符号再拼接,std::format 不提供这种模式
  • 若需前导零对齐,用 {:08b},但注意这仍按无符号解释被格式化的值

示例:

std::string s = std::format("{:b}", 42); // "101010"

位运算右移 + & 1 比除法快,但要注意有符号右移行为未定义

在循环实现里,用 n & 1 取最低位、n >>= 1 右移,比 n % 2n / 2 更高效,尤其对大数或高频调用场景。

但致命坑在于:对 int 做右移,C++ 标准规定“符号位扩展”行为是实现定义的。GCC/Clang 默认算术右移(负数补 1),但严格来说不能依赖——所以务必先转成无符号类型再操作。

  • 别写 int x = -5; while(x) {x >>= 1;} —— 可能死循环
  • 正确做法是转 unsigned intuint32_t,再移位
  • 如果原始值可能大于 uint32_t 范围(比如 long long),得选对应无符号类型,否则高位丢失

真正麻烦的从来不是“怎么转”,而是你没想清楚:这个二进制字符串到底给谁看?调试用、存配置、做位掩码,还是网络协议里发?不同用途,对前导零、符号、位宽、端序的要求天差地别。别急着套函数,先盯住下游怎么消费它。

text=ZqhQzanResources