【问题标题】:C++ bitwise complement in unsigned integer returns negative values无符号整数中的 C++ 按位补码返回负值
【发布时间】:2026-01-01 10:55:02
【问题描述】:

我只是想在 C++ 中使用 ~ 运算符进行按位补码:

例如:

NOT 0101
--------
    1010

所以在下面的代码中,我期望得到1010,但我得到的是负数。虽然我用unsigned 类型定义了值,但这怎么可能?

#include <iostream>
#include <stdio.h>
#include <string>
#include <bitset>
using namespace std;

int tob(int num) {
    if (num == 0)
        return 0;
    return (num % 2) + 10*tob(num/2);
}

long unsigned int tol(string st) {
    long unsigned int num = bitset<100>(st).to_ulong();
    return num;
}


int main()
{
    unsigned int x = tol("0101");
    unsigned int z = ~x;
    printf("%10d (decimal %u)\n", tob(z), z);
    // -110 (decimal -6)
    cout << tob(z) << endl; // -110
    cout << z << endl; // -110
}

我如何在 C++ 中从 not 0101 获取 1010

谢谢!

【问题讨论】:

  • 您似乎在代码中以奇怪的方式混合了二进制和十进制表示。我不确定您要完成什么,但您可以使用std::bitset 打印数字的二进制表示,如以下问题所示:*.com/questions/7349689/…
  • 这与你问的关于 go 的问题基本相同:*.com/q/32213029
  • 你的tob接受int并返回int,你用%d打印出来,你问我们为什么unsinged numbers变成了负数?

标签: c++ bit-manipulation long-integer bitwise-operators bitset


【解决方案1】:

unsigned int 通常有 32 位,所有这些都在这里反转:

NOT 0000 0000 0000 0000 0000 0000 0000 0101
-------------------------------------------
    1111 1111 1111 1111 1111 1111 1111 1010

如果您只想要最后 4 位并将其余位清零,请应用掩码:

unsigned int z = ~x & 0xf; // 1111 in binary

你也可以通过简单的按位异或得到想要的结果:

unsigned int z = x ^ 0xf;

顺便说一句,您的代码将无法打印较大数字的二进制表示,因为int 将无法保存大于 2^32 的值(以 100 0000 0000(十进制)开头)。为此,我建议使用std::bitset 或下面答案中的直接方法打印,而不是使用tob 函数。

【讨论】:

  • 这仍然不能解释为什么cout &lt;&lt; z &lt;&lt; endl; 打印一个负数,因为z 是无符号的。
【解决方案2】:

[...] 如何在 C++ 中从非 0101 得到 1010?

std::bitset 用于四个位。

std::bitset<4> x("0101");
auto z = ~x;
std::cout << '~' << x << '=' << z << std::endl;

Example on Coliru

【讨论】: