简单:什么是+&引用;操作员正在做什么(C位)?

简单:什么是+&引用;操作员正在做什么(C位)?,c,bits,C,Bits,我环顾四周,似乎找不到这个看似简单的问题的答案:在C(位)中,“+”或“-”到底是什么 例如,将1添加到11111111111111111111111111111111111时的表示形式是什么 我问这个是因为我正在阅读一些代码,我不知道是什么 ~0 + 1 他正在做什么。我是说,我们不能把1加到4294967295,对吗 谢谢 2^32=4294967296 因此,2^32-1是32位无符号整数(32位二进制数字)的最大值。2^32是可能值的数目。 4294967295是因为整数从0开始,

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

例如,将1添加到11111111111111111111111111111111111时的表示形式是什么

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

 ~0 + 1
他正在做什么。我是说,我们不能把1加到4294967295,对吗

谢谢

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


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

从技术上讲,C不添加或提取。编译器将其翻译成汇编代码,汇编代码被翻译成机器代码。体系结构应具有
ADD
指令

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

无论如何,这有一些信息

您可能还感兴趣的是负数在二进制中的表示方式,以及负数在算术运算中的适用性


常用的格式称为两个补码。你可以阅读更多关于这项工作原理的信息。

当然可以。由于您没有指定任何文本的类型,因此假定为“int”<代码>~0是
-1
,正如您所指出的,
-1+1
是零


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

让我们继续使用较小的数字,以便更容易地看到发生了什么

4位数字应为
0000
。从
1111开始
现在添加一个。该值现在为
1 0000
,您将看到该值为
0000

这就像普通的十进制加法一样。我们有
9
,然后在1位有
0
,在10位有
1
。如果我们有一个比我们有位更大的数字,计数器只是滚动到0,然后重新开始


现在,我们把它简化为正数。如果整数是有符号的,则从最大正数到最大负数,再循环到最大正数,最终会改变负数和正数以二进制形式存储的方式。

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

  • 在“两个补码”格式中,
    ~0==-1
    ,所以
    ~0+1==0

  • 在“一的补码”格式中,
    ~0==-0
    ,所以
    ~0+1==1

  • 在“符号幅度”格式中,
    ~0==INT\u MIN
    ,因此
    ~0+1==INT\u MIN+1

保证在所有系统上定义结果

另一方面,如果使用无符号数字,则始终会得到相同的结果

  • ~n
    定义为
    n
    类型的最大值减去
    n
    。所以
    ~0u
    就是
    UINT\u MAX

  • x+y
    保证环绕,因此标准保证所有系统上的
    UINT_MAX+1==0

  • 因此,所有系统上的
    ~0u+1==0u
    都是有保证的


正如你所看到的,这和二的补语是一样的,这解释了二的补语的流行。不使用二的补码的系统现在很少见,不包括bigint库。

打包BCD与任何东西有什么关系?是的,那是愚蠢的。不注意。谢谢。无符号整数溢出从来都不是未定义的,它是显式定义为环绕的。只有带符号整数溢出才会导致问题,并且在某些情况下它只会导致未定义的行为。很抱歉我不知道,但我认为~0是11111111111111111111111111111??Pauliwago:是的,并且以带符号的数字表示(如果您没有明确说明其他情况,这是C中的默认值)“全一”值被解释为
-1
。阅读“二的补码”数字——这是整数存储在电脑内存中的方式。我的答案包含一个指向二的补码信息的链接。要用引号补充迪特里希·埃普的评论,C99的6.2.5:9说涉及无符号操作数的计算永远不会溢出,因为不能由结果无符号整数类型表示的结果将按大于结果类型可表示的最大值一的数字进行模化一个警告:在不支持负零的1的补码实现中,
~0
的行为是未定义的(C99§6.2.6.2)。这有点悲哀。