C 中整数变量的 1s 补码表示

1s complement representation for integer variable in C

提问人:user3737377 提问时间:8/13/2023 最后编辑:journpyuser3737377 更新时间:8/19/2023 访问量:108

问:

我是 C 的新手,所以我对这段代码感到困惑。 我想知道一个人的补码将如何用于整数变量

法典:

int f = 45;
printf("Value of %d is = %d",f,~f);

现在输出是

“值 45 是 = -46”

我的问题是:这是整数变量,在我的编译器中,int 为 4 个字节,即 2^32

所以这意味着它将在机器中表示为

4294967296  . . . . . . . 32 16 8 4  2 1

0                          1   0 1 1  0 1

右?或者它将表示到前 8 位?

如果表示到 32 位,那么“32”位和“4294967296”之间的数字将是 0,因为这是 4 个字节的整数,这需要以这种方式表示,对吗?

数字的表示呢,那我需要一些参考点。 我会自己研究,假设 int 是 4 个字节,如果我写 int a = 3;它是用 8 位表示 00000011 表示还是用 00000000000000000000000000000011 表示,如果我写 int a = 257, 它会用0000000100000001表示还是用00000000000000000000000100000001表示 请给我一些提示或解释?

然后,当我们要计算 ~ 1s 补码时,我们将反转 bit 的值,因此在这种情况下,32 和 4294967296 之间的位将从 0 变为 1 ?如果是这样,那么它会成为一些很大的价值吗?这个 -46 是如何计算的?

c 一补码

评论

1赞 Uri Raz 8/13/2023
您运行程序的计算机使用二补码,就像现在的大多数计算机一样。
0赞 user3737377 8/13/2023
好的,但是数字的表示呢,我需要一些参考点,然后我会自己研究,假设 int 是 4 个字节,如果我写 int a = 3;它会用 8 位表示 00000011 表示还是用 00000000000000000000000000000011 表示,如果我写 int a = 257,它会用 0000000100000001 表示还是用 00000000000000000000000100000001 表示 请给我一些提示或解释?
0赞 chqrlie 8/13/2023
最高有效位不是它实际上是有符号类型的符号位,对于 ,它表示4294967296intunsigned int2147483648
0赞 stark 8/13/2023
无论分配的值如何,int 都是 32 位。因此,即使 3 可以容纳一个字节,它仍然是一个 32 位数字。
0赞 BoP 8/13/2023
现在是时候忘记这一点了。C23 和 C++23 都只允许 2 的补码,因为在实践中没有使用其他任何东西。因此,如果您不完全理解 1s 补码,那也没关系!

答:

0赞 Mustafa Hakan Solmaz 8/13/2023 #1

以十六进制打印结果可能会让您对 1-补码有所了解

#include <stdio.h>

int main() {

    int f = 45;
    printf("int: %d int1s : %d \n",f,~f);
    //since each byte is two hex digits, 4 bytes correspond to 8 digits
    printf("hex : %08x , 1scomp : %08x \n",f,~f);
    return 0;
}

将导致以下输出: 在十六进制表示法中,每个数字的 1 补码加起来应为 15(0xF),如本例所示。

int: 45 int1s : -46 
hex : 0000002d , 1scomp : ffffffd2 
1赞 nielsen 8/13/2023 #2

正如你所说,结果的“一补码”值,即查看二进制表示,将翻转 .因此,通常称为“按位 NOT”运算符。在 32 位的系统上,该类型的所有值都使用完整的 32 位表示,而不考虑该值。因此,例如“3”表示为,因此“~3”是。~ff~ff~int00000000 00000000 00000000 0000001111111111 11111111 11111111 11111100

与大多数现代计算机一样,您的计算机不使用“一补码”来表示负整数。它使用“二的补语”来代替。因此,在打印时,它的值将打印位模式在“二补码”中表示的值,而不是“一补码”。~f~f

规则很简单。如果是正整数,则在“二的补码”中:f

-f == ~f+1

或者,等效地:

~f == -(f+1)

因此,在这种情况下,其中 = 45,我们得到 = -(45+1) = -46。f~f

评论

0赞 user3737377 8/19/2023
我没有完全理解,但一旦获得那么多的理解,我就会研究这个问题。谢谢
0赞 nielsen 8/19/2023
@user3737377 不客气。我推荐链接的维基百科页面了解详情。
0赞 0___________ 8/13/2023 #3

数字的表示呢,那么我需要一些参考点 我会自己研究,假设 int 是 4 个字节,如果我写 int a = 3;它会用 8 位表示 00000011 表示还是用 00000000000000000000000000000011 表示,如果我写 int a = 257,将 它用 0000000100000001 或 00000000000000000000000100000001 请给我一些提示或 对此的解释?

257 不能以 8 位存储,所以它将是 .所以你的逻辑是错误的,因为 8 位字节不能神奇地变成 16 位。00000001

更复杂的是,32 位数字不会像您显示的那样存储(在大多数系统上,因为它们使用很少的字节序表示法)。它将是:

byte 0   byte 1   byte 2   byte 3
00000001 10000000 00000000 00000000

对于 C 语言中的补语(使用标准运算符时),您需要将计算机更改为例如 PDP-1。enter image description here您甚至可以玩 Spacewars 游戏!enter image description here