当x = 0x80000000时,〜(x-1)和~x 1之间的差异

我使用的语言是C.
x和n的类型是int.

我有一个代码如下

printf("x=%x,n=%d,first=%x,second=%x\n",x,n,((~(x+0xffffffff))>>n),((~x+1)>>n));

显示了x,n的值和两个移位x的补数的n位方法.
当x = 0x80000000时,〜(x 0xffffffff)= 0x8000000,~x 1 = 0x80000000,但当将这两个移位n位时,结果是不同的.

顺便说一句,如果我把0xffffffff改为~1 1(即〜(x(~11)),结果与~x 1相同

我想知道为什么会这样.谢谢.

解决方法

Pavan Manjunath现在删除的答案对于一个案例有正确答案,假设int像往常一样是32位类型.整数常量
0xffffffff

具有值2 ^ 32 – 1并且不能由int表示,但它可以表示为unsigned int.所以它的类型是unsigned int(6.4.4.1).因此,x被转换为unsigned int以进行加法,并且

((~(x+0xffffffff))>>n)

评估为

((~(0x80000000u + 0xffffffffu)) >> n)
((~0x7fffffffu) >> n)
(0x80000000u >> n)

如果0 <= n <1,则值为2 ^(31-n) 32(如果n超出该范围,则为未定义的行为). 对于另一种情况,ouah的答案是正确的,当x = 0x80000000是int时,~0x8000000 = 0x7fffffff = INT_MAX和INT_MAX 1是未定义的行为,因为有符号整数溢出. 然而,常见的行为是环绕,然后加法的结果是有符号整数0x80000000,负整数的右移是实现定义的行为(6.5.7). Common正在使用符号扩展进行移位,这将产生结果-2 ^(31-n),然后通过printf转换说明符%将其解释为unsigned int,值为2 ^ 32 – 2 ^(31-n) X.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...