1

I'm confused about the negation operation after doing the bit shift. For example:

-(1<<7) is 0xffffff80

But why are the most significant bits filled with 1? I'm confused about what the operation - means here.

Edit 1: I used printf("%#08x\n", -(1<<7)) to print out the value.

4

5 回答 5

2

首先,感谢您提出这个问题。通常最好编写一个测试程序来说明您不确定的事情,然后尝试不同的事情来找出细节。

评论,比如 UB,通常是不准确的。在这种情况下,发生的事情是非常可预测和合理的,这正是有经验的程序员应该期待的。

我在 Eclipse/Microsoft C 编译器上运行了以下代码:

#include <stdio.h>
main()
{
    int i;
    unsigned int j;

    i = -(1<<7);
    printf("%i\n", i);
    printf("%08x\n", i);

    j = -(1<<7);
    printf("%u\n", j);
    printf("%08x\n", j);
}

并得到以下输出:

-128
ffffff80
4294967168
ffffff80

这些是预期的,因为:(1 << 7) 等于 128,而 -(128) 是 -128。i的printf内容恰好以二进制形式生成 -128 的值。

看到这一点的方法是取 ffffff80 = 0000007f + 1 = 00000080 的 2 的补码,即二进制 128。因此,您可以看到取数字的 2 的补码就是我们取整数的负数的方式。

真正大的数字是相同内容的无符号值。

尽可能写一点代码来检查东西是如何工作的!

于 2013-08-22T18:30:00.140 回答
0

答案很简单,这取决于负数在计算机内存中的保存方式。

我想 1 << 7 的含义对你来说很明显。它等于 128。你的“-”号只是意味着你想改变结果的符号,所以最终的结果是 -128。

但是为什么你得到了一些不同的东西?这是答案:

通常有两种类型的变量:有符号和无符号。两种类型都保存在实际上不知道开始使用哪种类型的内存中。程序员知道存储了什么样的数字。

当您将变量声明为无符号时,它可以存储从 0 到 n 的值,其中 n 是某种类型变量的最大值。

当您使用有符号时,您可以在那里存储一个从定义的负值到某个定义的正值的值。

使用无符号变量时,计算is值非常简单。请考虑一个 8 位(1 字节)无符号变量的简单示例:

如前所述,最小值为 0,设置所有 8 位时最大值为 255。

对于有符号类型的变量,使用了一种特殊的格式:从 0 到 127 的数字以与无符号类型相同的方式保存。而 127 的值是 8 位变量的最大值。最小值为 -128,存储为 0b10000000 或 0x80。下一个是-127,保存为0b10000001或0x81等。最大的负数是 -1,保存为 0b11111111 或 0xFF。

所以如果你有一个字节值 0xff 它可以是:255(无符号时)或-1(有符号时)。此处用于有符号变量类型的符号称为 U2 - 请阅读此内容。

在您的特定情况下,您似乎有一个有符号(-128)值,该值被读取为无符号值。在您的情况下,使用了 32 位(4 字节)变量(可能(无符号)int),因此它看起来有点不同(结果更长),但您可能会看到一些相似之处:U2 中 -128 的最后两位数字无论使用多少位来存储值,系统都将始终为 0x80。

于 2013-08-22T17:46:24.730 回答
0

-(1<<7)不是0xffffff801<<7是 1 乘以 2 的 7 次方,即 128。-128 也是如此-(1<<7)。为什么您看到它的最可能的解释是您通过将其传递给与格式说明符一起使用0xffffff80来调用未定义的行为。接受一个参数(也可以接受一个有符号的,只要该值是非负的),但您传递的参数具有类型并且是负数。因此,会产生未定义的行为。printf%x%xunsigned intintint

于 2013-08-22T17:33:53.213 回答
0

减号运算符(实现定义但最有可能)将对其参数执行二进制补码(在这种情况下为十进制的 128)。2 的补码是:减 1 并将所有位取反。

于 2013-08-22T17:17:34.697 回答
0

有效位用 1 填充,因为它们代表符号并且重复它们不会影响值。对于正数,100100000010都相等。并且由于 1 的最高有效位表示负数,因此在负数前面放置尽可能多的 1 不会影响幅度。您可以使用 2s 补码算法检查这一事实。

于 2013-08-22T17:21:27.940 回答