我在 C 和 C++ 的上下文中看到了这些,但是有符号变量和无符号变量有什么区别?
8 回答
虽然通常称为“符号位”,但我们通常使用的二进制值没有真正的符号位。
大多数计算机使用二进制补码算法。通过取一个补码(翻转所有位)并加一来创建负数:
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,但我现在找不到任何对它的引用。
有符号变量使用一位来标记它们是正数还是负数。无符号变量没有这个位,因此它们可以在同一空间中存储更大的数字,但只能存储非负数,例如 0 和更高。
更多信息:无符号和有符号整数
无符号变量只能是正数,因为它们缺乏表明它们是负数的能力。
这种能力称为“符号”或“签名位”。
一个副作用是,如果没有签名位,它们就多了一个位可以用来表示数字,它可以表示的最大数字加倍。
有符号变量可以是 0、正数或负数。
无符号变量可以为 0 或正数。
有时会使用无符号变量,因为可以使用更多位来表示实际值。给你更大的范围。例如,您还可以确保不会将负值传递给您的函数。
unsigned 用于当你的值必须为正时,这里没有负值,如果有符号为 int 范围 -32768 到 +32767 如果无符号为 int 范围 0 到 65535
无符号变量是在内部没有数学符号(加号或减号)表示的变量,只能存储“零”或正值。假设无符号变量的大小为n 位,那么它可以表示 2^n (2 power n) 个值 - 0 到 (2^n -1)。另一方面,有符号变量会“丢失”一个用于表示符号的位,因此它可以存储从 -(2^(n-1) -1) 到 (2^(n-1)) 的值,包括零。因此,有符号变量可以存储正值、负值和零。
PS:
在内部,数学符号可以用一个补码形式,二进制补码形式或用符号位表示(例如:0 -> +,1-> -)
所有这些方法都有效地将可表示值的范围划分为n位( 2^n) 分为正、负和零三部分。
这只是我的两分钱。
我希望这有帮助。
这可能不是确切的定义,但我会给你一个例子:如果你要创建一个从系统时间获取的随机数,这里使用无符号变量是有益的,因为随机数的范围很大,因为有符号数给出正数和负数。由于系统时间不能为负,我们使用无符号变量(仅正数)并且我们有更广泛的随机数。