【问题标题】:difficulty understanding signed not理解困难 未签名
【发布时间】:2019-03-13 23:40:25
【问题描述】:

我无法理解为什么 c 在以下程序中等于 -61:

   main() {
       unsigned int a = 60;     // 60 = 0011 1100   
       unsigned int b = 13;     // 13 = 0000 1101
       int c = 0;           
       c = ~a;          //-61 = 1100 0011
       printf("Line 4 - Value of c is %d\n", c );
   }

我确实了解 NOT 运算符在 0011 1100 上的工作原理(解决方案是 1100 0011)。但我不确定为什么十进制数加 1。这是从 unsigned int(来自 a)到有符号 int(来自 c)的某种类型转换吗?

【问题讨论】:

标签: c bitwise-operators


【解决方案1】:

二进制补码(标准有符号格式)从正数到负数的转换构成按位反转,并加一。

请注意,为简单起见,我使用的是单个有符号字节。

So if 60 = 0011 1100
Then c   = 1100 0011 + 1
         = 1100 0100

对于有符号字节,最高有效位是负数, 所以

c = -128 + 64 + 4 = -60

您需要加 1 以说明最高有效位是 -128,而最大的正数是 0111 1111 = 127。所有负数都有一个 1 表示 -128 需要偏移。

当您将 0 转换为 -0 时,这一点很容易看出。将 00000000 取反,得到 11111111,加一则返回 00000000。对 1 到 -1 执行相同操作,得到 11111111 - 可能的最大负数。

【讨论】:

  • 不错的答案。二进制补码可能看起来是一种处理有符号数的复杂而奇怪的方式,但实际上它是一种非常聪明的编码,可以简化 CPU 的设计方式。它允许一个简单的无符号二进制加法器电路工作,无论相加量的符号如何,并消除了具有正零值或负零值的歧义。
  • 您能否澄清一下几点:1)我确实知道如何做 2 的恭维,但我们为什么要这样做? 2 的补语以什么方式连接到 NOT 运算符? 2) 我了解这些数字的来源:c = -128 + 64 + 4 = -60,但答案是 c = -61。减法(或加 -1)从何而来?
  • 所以 c 是 -61 而不是 -60 的原因是因为 NOT 运算符实际上并没有从正数转换为负数,它只是翻转位。这只是从 60 到 -60 的过程的一半,另一半是在翻转位后加 1。所以 c = ~a + 1 是您“手动”进行二进制补码转换的方式,但 c = -1*a 会在后台为您完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-14
  • 1970-01-01
  • 2015-11-09
  • 1970-01-01
相关资源
最近更新 更多