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

46qrfjad  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(117)

我是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位表示0000000000000000000000000000000000000011来表示,如果我写int a = 257,它是用0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
然后,当我们要计算~1s补码时,我们要反转位的值,因此在这种情况下,32和4294967296之间的位将从0变为1?如果是这样,那么它将成为一些大的价值?这-46是怎么计算出来的?

a0x5cqrl

a0x5cqrl1#

正如你所说,~f导致f"one's complement"值,即查看二进制表示,~f将翻转f的所有位。因此,~通常被称为“按位非”运算符。在int为32位的系统上,该类型的所有值都使用完整的32位表示,而不管值是什么。因此,例如“3”表示为00000000 00000000 00000000 00000011,因此“~3”表示为11111111 11111111 11111111 11111100
您的计算机,像大多数现代计算机一样,不使用“一的补数”来表示负整数。它使用"two's complement"代替。因此,当打印~f的值时,它将打印~f的位模式以“二进制补码”表示的值,而不是“一进制补码”。
规则很简单。如果f是一个正整数,那么在“二进制补码”中:

-f == ~f+1

或者,等价地:

~f == -(f+1)

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

p1tboqfb

p1tboqfb2#

用十六进制打印结果可能会给你给予一些关于补码的概念

#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
qlzsbp2j

qlzsbp2j3#

关于数字的表示,我需要一些参考点,然后我会自己研究,假设int是4字节,如果我写int a = 3;它是用8位表示0000000000000000000000000000000000000011来表示,如果我写int a = 257,它是用0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
257不能存储在8位中,所以它将是00000001。所以你的逻辑是错误的,因为8位字节不能神奇地变成16位。
更复杂的是,32位的数字将不会被存储(在大多数系统上,因为他们使用little endian notation)的方式显示。它将是:

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

对于C语言中的补码运算(当使用标准运算符时),您需要将计算机更改为例如PDP-1。

您甚至可以玩Spacewars游戏!

相关问题