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

前端之家收集整理的这篇文章主要介绍了当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&C++相关文章