2

我环顾四周,似乎找不到这个看似简单的问题的答案:C(位)中的“+”或“-”到底是什么?

比如11111111 11111111 11111111 11111111加1代表什么?

我问这个是因为我正在阅读一些代码,但我不知道是什么

 ~0 + 1

是在做。我的意思是,我们不能将 1 添加到 4294967295 对吗?

谢谢!

4

5 回答 5

4

答案将取决于您的计算机对有符号数字使用的表示形式。

  • 在“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 库。

于 2012-10-13T04:41:31.607 回答
3

当然,我们可以。由于您没有指定任何文字的类型,因此假定为“int”。~0-1,正如您所指出的,并且-1 + 1为零。

另一方面,如果这些是无符号数字,那么您就会出现整数溢出。PC 深处的实际添加指令仍然返回零,它只是设置了一个“进位”标志,让 C 知道发生了一些奇怪的事情。在 C 规范中,整数溢出的结果是未定义的,因此您/可能/得到零,但您不能依赖它。

于 2012-10-13T04:28:00.757 回答
1

让我们坚持使用较小的数字,以便更容易看到正在发生的事情。

一个 4 位数字将是0000. 现在开始1111添加一个。现在的值是1 0000您将看到的0000

就像正常的以十为基础的加法一样。9然后我们在0个位和1十位都有。如果我们的数字大于我们的位数,则计数器将滚动到 0 并重新开始。

现在,这被简化为谈论正数。如果 int 是有符号的,则从最大正数到最大负数并循环回到最大正数,最终以负数和正数以二进制形式存储的方式进行。

于 2012-10-13T04:28:14.367 回答
0
2^32=4294967296

因此,2^32-1是 32 位无符号整数(32 个二进制数字)的最大值。2^32 是可能值的数量。
4294967295是因为整数从0开始,但是我们的计数从1开始。
这是一个整数范围,当你给这个数字加1时,它就超出了整数范围,这就是为什么我们不能给4294967295加1的原因。

+是加法算术运算符 &-是减法算术运算符

于 2012-10-13T04:26:33.363 回答
0

从技术上讲,C 不添加或提取。编译器将其翻译成汇编代码,然后再翻译成机器代码。架构应该有一个ADD指令。

我相信使用基本逻辑门可以通过多种方式完成操作。

无论如何,这本书有一些信息。

您可能还感兴趣的是负数如何以二进制表示,以及它如何适合算术运算。

使用的常用格式称为二进制补码您可以在此处阅读有关其工作原理的更多信息。

于 2012-10-13T04:27:06.983 回答