我环顾四周,似乎找不到这个看似简单的问题的答案:C(位)中的“+”或“-”到底是什么?
比如11111111 11111111 11111111 11111111加1代表什么?
我问这个是因为我正在阅读一些代码,但我不知道是什么
~0 + 1
是在做。我的意思是,我们不能将 1 添加到 4294967295 对吗?
谢谢!
答案将取决于您的计算机对有符号数字使用的表示形式。
在“Two's Complement”格式中,~0 == -1
,所以~0 + 1 == 0
。
在“一个人的补码”格式中,~0 == -0
,所以~0 + 1 == 1
。
在“符号幅度”格式中,~0 == INT_MIN
,所以~0 + 1 == INT_MIN + 1
。
保证在所有系统上定义结果。
另一方面,如果您使用无符号数,您将始终得到相同的结果。
~n
被定义为 's 类型的最大值n
,减号n
。~0u
也是如此UINT_MAX
。
x + y
保证环绕,因此标准保证UINT_MAX + 1 == 0
在所有系统上。
因此,~0u + 1 == 0u
在所有系统上,都有保证。
如您所见,这与二进制补码的行为相同,这解释了二进制补码的流行。如今,不使用二进制补码的系统很少见,不包括 bigint 库。
当然,我们可以。由于您没有指定任何文字的类型,因此假定为“int”。~0
是-1
,正如您所指出的,并且-1 + 1
为零。
另一方面,如果这些是无符号数字,那么您就会出现整数溢出。PC 深处的实际添加指令仍然返回零,它只是设置了一个“进位”标志,让 C 知道发生了一些奇怪的事情。在 C 规范中,整数溢出的结果是未定义的,因此您/可能/得到零,但您不能依赖它。
让我们坚持使用较小的数字,以便更容易看到正在发生的事情。
一个 4 位数字将是0000
. 现在开始1111
添加一个。现在的值是1 0000
您将看到的0000
。
就像正常的以十为基础的加法一样。9
然后我们在0
个位和1
十位都有。如果我们的数字大于我们的位数,则计数器将滚动到 0 并重新开始。
现在,这被简化为谈论正数。如果 int 是有符号的,则从最大正数到最大负数并循环回到最大正数,最终以负数和正数以二进制形式存储的方式进行。
2^32=4294967296
因此,2^32-1
是 32 位无符号整数(32 个二进制数字)的最大值。2^32 是可能值的数量。
4294967295是因为整数从0开始,但是我们的计数从1开始。
这是一个整数范围,当你给这个数字加1时,它就超出了整数范围,这就是为什么我们不能给4294967295加1的原因。
+
是加法算术运算符 &-
是减法算术运算符