-5

我如何制作输出NOT(x)的程序?

例子:

  • 12到3
  • 0到1
  • 2比1

解释:

  • 1100 至 0011
  • 0到1
  • 01 至 10

    printf("%i\n%i\n%i\n", ~12, ~0, ~2);

印刷:

-13
-1
-3

printf("%i\n%i\n%i\n", !12, !0, !2);

印刷:

0
1
0
4

3 回答 3

5

您对 printf 的可变参数被提升为int,将其视为首先将您的位存储在变量中(int),然后对它们执行位而不是:

int x = 12;     // 0x0000000C
int y = ~x;     // 0xFFFFFFF4 

y 现在是负符号 int 值。

将您的格式字符串和值更改为无符号,它可能更接近您正在寻找的内容:

int main(int argc, char *argv[])
{
    unsigned int x = 12;
    unsigned int y = ~x;
    printf("%u:%u\n",x,y);
    return EXIT_SUCCESS;
}

结果:

12:4294967283

如果您正在寻找打印值的实际“位”的功能,可以在这里找到一个很好的起点,因为 printf() 没有本机位二进制打印功能。

最后,如果您对翻转感兴趣的只是最重要的非零位,请务必在输入值为零 (0) 时对您的情况进行特殊处理。你真的需要一个“这么多位对我来说很重要”的价值来真正做到这一点。

编辑:一个非常低效的位串:显然,如果没有数字类型 作为前导模板参数,这将不起作用。自行决定使用(和危险)。

template<typename T, size_t N=sizeof(T)*8>
std::string bit_string(T value, size_t maxbits=N)
{
    static const char *one = "1";
    static const char *zero = "0";
    std::string result;

    maxbits = std::min(maxbits, N);
    for (size_t i=0;i<maxbits;i++)
    {
        result = ((value & T(1)) ? one : zero) + result;
        value >>= 1;
    }
    return result;
}
于 2012-11-02T15:10:58.960 回答
3

您的第一个示例之所以如此工作,是因为负数的二进制补码二进制表示法。

例如,该值12实际上将表示为0000000000001100一个 16 位整数,并且很可能实际上是一个 32 位整数。这个值的位非是1111111111110011,这是-13二进制补码。

您的第二个示例代码使用布尔非运算符。C++ 将任何非零值视为真,而“非真”的值始终false为 或整数0。同样,!0表示“非假”并将-1作为 C++ 的“标准真”值返回。(使用此值是因为!0 == -1在二进制补码中,所以!false~false是等价的操作。)

所以:你打算做的事情比你想象的要复杂。您所说的“NOT(x)”实际上是“二进制数的按位非,截断为有效数字的最小数量,并解释为无符号数。” 这并不像你说的那么简单!

有效数字部分尤为重要。如果所有数字都是 8 位无符号数,则 "NOT(2)" 实际上253 不是(如您所说)1

有趣的是,您的定义意味着 NOT 不再可逆:NOT(NOT(12))is not 12,但实际上会NOT(12) = 3and then NOT(3) =0

所以,为了实现你想要的:

  1. 计算出原始数字的最高位是多少(这是小于原始数字的 2 的最大幂?)。(表示此值以sd供稍后使用。)
  2. 按位反转您的原始数字
  3. 按位与结果2 ^ (sd) - 1

例如,使用数字12

  1. 最高有效数字是4(2 ^ 4 = 16)
  2. 倒数(假设为 16 位)是1111111111110011
  3. 2 ^ 4 - 1 = 15二进制是0000000000001111
  4. 1111111111110011 AND 0000000000001111 == 0000000000000011这就是你想要的结果。
于 2012-11-02T15:12:48.980 回答
0

好吧,如果你想翻转 int 中的所有位,你可以从 中减去值int max,或者翻转一个短,从short max... 至少我认为这就是你要问的。

于 2012-11-02T15:11:05.190 回答