75

我在 C 和 C++ 的上下文中看到了这些,但是有符号变量和无符号变量有什么区别?

4

8 回答 8

135

有符号变量,例如有符号整数,将允许您表示正数和负数范围内的数字

无符号变量,例如无符号整数,仅允许您以正数和零表示数字

相同类型的无符号和有符号变量(例如intbyte)都具有相同的范围(范围分别为 65,536 和 256 个数字),但无符号可以表示比相应的有符号变量更大的幅度数

例如, anunsigned byte可以表示从0to的值255,而signed byte可以表示-128to 127

有符号数表示的维基百科页面解释了位级别表示的差异,整数(计算机科学)页面提供了每个有符号/无符号整数类型的范围表。

于 2009-03-07T04:14:41.957 回答
45

虽然通常称为“符号位”,但我们通常使用的二进制值没有真正的符号位。

大多数计算机使用二进制补码算法。通过取一个补码(翻转所有位)并加一来创建负数:

      5 (decimal) -> 00000101 (binary)
      1's complement: 11111010
      add 1: 11111011 which is 'FB' in hex


这就是为什么有符号字节的值从 -128 到 +127 而不是 -127 到 +127:

      1 0 0 0 0 0 0 0 = -128
      1 0 0 0 0 0 0 1 = -127
          - - -
      1 1 1 1 1 1 1 0 = -2
      1 1 1 1 1 1 1 1 = -1
      0 0 0 0 0 0 0 0 = 0
      0 0 0 0 0 0 0 1 = 1
      0 0 0 0 0 0 1 0 = 2
          - - -
      0 1 1 1 1 1 1 0 = 126
      0 1 1 1 1 1 1 1 = 127
      (将 1 加到 127 给出:)
      1 0 0 0 0 0 0 0   我们在此图表顶部看到的是 -128。


如果我们有一个正确的符号位,则值范围将是相同的(例如,-127 到 +127),因为为符号保留了一位。如果最高有效位是符号位,我们将有:

      5 (decimal) -> 00000101 (binary)
      -5 (decimal) -> 10000101 (binary)

在这种情况下,有趣的是我们同时有一个零和一个负零:
      0 (decimal) -> 00000000 (binary)
      -0 (decimal) -> 10000000 (binary)


我们没有带二进制补码的 -0;-0 是 -128 (或者更一般地说,比最大的正值多一)。我们用一个补码来做;所有 1 位都是负 0。

在数学上,-0 等于 0。我依稀记得有一台计算机 -0 < 0,但我现在找不到任何对它的引用。

于 2010-10-11T02:37:37.920 回答
19

有符号变量使用一位来标记它们是正数还是负数。无符号变量没有这个位,因此它们可以在同一空间中存储更大的数字,但只能存储非负数,例如 0 和更高。

更多信息:无符号和有符号整数

于 2009-03-07T04:12:29.233 回答
3

无符号变量只能是正数,因为它们缺乏表明它们是负数的能力。

这种能力称为“符号”或“签名位”。

一个副作用是,如果没有签名位,它们就多了一个位可以用来表示数字,它可以表示的最大数字加倍。

于 2009-03-07T04:15:55.933 回答
3

有符号变量可以是 0、正数或负数。

无符号变量可以为 0 或正数。

有时会使用无符号变量,因为可以使用更多位来表示实际值。给你更大的范围。例如,您还可以确保不会将负值传递给您的函数。

于 2009-03-07T04:54:13.593 回答
2

unsigned 用于当你的值必须为正时,这里没有负值,如果有符号为 int 范围 -32768 到 +32767 如果无符号为 int 范围 0 到 65535

于 2010-07-15T17:52:58.930 回答
0

无符号变量是在内部没有数学符号(加号或减号)表示的变量,只能存储“零”或正值。假设无符号变量的大小为n 位,那么它可以表示 2^n (2 power n) 个值 - 0 到 (2^n -1)。另一方面,有符号变量会“丢失”一个用于表示符号的位,因此它可以存储从 -(2^(n-1) -1) 到 (2^(n-1)) 的值,包括零。因此,有符号变量可以存储正值、负值和零

PS:
在内部,数学符号可以用一个补码形式,二进制补码形式或用符号位表示(例如:0 -> +,1-> -)
所有这些方法都有效地将可表示值的范围划分为n位( 2^n) 分为正、负和零三部分。

这只是我的两分钱。

我希望这有帮助。

于 2009-03-07T04:58:13.240 回答
-1

这可能不是确切的定义,但我会给你一个例子:如果你要创建一个从系统时间获取的随机数,这里使用无符号变量是有益的,因为随机数的范围很大,因为有符号数给出正数和负数。由于系统时间不能为负,我们使用无符号变量(仅正数)并且我们有更广泛的随机数。

于 2016-06-22T11:12:10.170 回答