6

有些东西我不明白:

C 中的Asigned char用 8 位表示:00000000

  • 0 是0000 0000=> 0
  • 1 0000 0001=> 1
  • ...
  • 127 0111 1111=> 127

所以我认为第 8 位是符号位。所以我认为:

  • 128 1000 0000=> 0
  • 129 1000 0001=> -1

但不是!

尝试这个:

int main(int argc, const char *argv[])
{
    int i;
    for (i = 0; i < 256; i++) {
        printf("%3d = %d\n", i, (signed char)i);
    }
    return 0;
}

你得到:gcc -o tt tt.c ; ./tt | more

  • ...
  • 126 = 126
  • 127 = 127
  • 128 = -128
  • 129 = -127
  • 130 = -126
  • 254 = -2
  • 255 = -1

怎么会?

4

5 回答 5

8

这称为有符号整数的 2 的补码表示,用于所有整数类型。

这个想法是这样的:CPU 中的加法器会在发生溢出时简单地忽略并回绕,因此您实际上是在一个模数环上进行计算。所以,如果你从零中减去 1,你会得到

 00000000 = 0
-00000001 = 1
--------------
 11111111 = -1

等等。

这样,您的计算机在计算时可以简单地忽略符号。这对于乘法甚至是正确的,例如在这个例子中 3 和 -2 的乘法(为简洁起见 4 位算术):

0011 * 1110
-----------
       0000
      0011
     0011
    0011
-----------
     101010
truncated to 4 bits: 1010

1010是 的负数0110,即 6,因此结果应该是 -6。

只有很少的点需要考虑符号性,例如比较、除法和转换为更大的整数类型。比较相对简单,演员表的工作方式如下:

00000001 -> 0000000000000001
10000000 -> 0000000010000000 (unsigned extension 128 -> 128)
10000000 -> 1111111110000000 (sign extension, the sign bit is copied into all new bits, preserving the value of negative numbers -128 -> -128)
于 2013-08-02T09:44:24.387 回答
5

这是因为 8 位 2 的补码编码。带符号的字符范围是从 -128 到 127。

EDIT1:回复@Grijesh 的评论

-128 和 +128 具有相同的表示:10000000。因此,为了避免混淆并制定规则All bit-patterns with 1 in higher-order bit represent negative numbers,决定将其视为 -128,这使得范围从 -128 到 127 而不是 -127..+128。

于 2013-08-02T09:42:48.413 回答
4

在二进制补码中,最左边的位是负数,其他位是正数,所以

1000 0000

=> -128

1000 0001

=> -128 + 1 = -127

因此最大的数字是 0111 1111 (127),最小的数字是 1000 0000 (-128)

于 2013-08-02T09:46:27.940 回答
2

你可以把它想象signed datatypes成一个时钟。12 小时后总是会打到 12 点。 Char范围-128+127。所以当你127按照我的时钟规则击中时,下一次击中将是-128

我建议你做一些二进制计算。

欲了解更多信息,请阅读 http://en.wikipedia.org/wiki/Two%27s_complement

于 2013-08-02T09:45:55.897 回答
1

在 c 中,char 是唯一的 1 字节内存分配意味着总共 8 位。这是因为 8 位 2 的补码编码。带符号的字符范围是从 -128 到 127。
因为你使用了。

   printf("%3d = %d\n", i, (signed char)i);
于 2013-08-02T09:48:35.240 回答