伸缩式导轨:一个程序小问题

来源:百度文库 编辑:高校问答 时间:2024/04/27 14:47:43
#include"stdio.h"
main()
{int x=1,y=-1;
printf("%d\n",~x|x);
printf("%d\n",x^y);}
运行后结果为
-1
-2
本人不知道为什么是这个结果!
高手教我算算啊!

x,y均为int型,其二进制形式为16位。
x = 1 的二进制形式为:0000 0000 0000 0001
那么,~x的二进制形式为:1111 1111 1111 1110
~x | x 的运算结果为:1111 1111 1111 1111,其值为-1.

y=-1的二进制形式为:1111 1111 1111 1111
x ^ y 的运算结果为:1111 1111 1111 1110,其值为-2.

不知你对按位与、按位或、按位异或的运算以及补码的表示形式了解多少!
1)按位取反(~):很简单,~0=1,~1=0
如 x = 0000 0000 0000 0001
则~x = 1111 1111 1111 1110
2)按位与(&):0&0=0, 0&1=0, 1&0=0, 1&1=1. 如:
x = 0000 0000 0000 0001
y = 1111 1111 1111 1111
x&y=0000 0000 0000 0001
3)按位或(|):0|0=0, 0|1=1, 1|0=1, 1|1=1. 如:
x = 0000 0000 0000 0001
y = 1111 1111 1111 1111
x|y=1111 1111 1111 1111
4)按位异或(^):0^0=0, 0^1=1, 1^0=1, 1^1=0. 如:
x = 0000 0000 0000 0001
y = 1111 1111 1111 1111
x^y=1111 1111 1111 1110
5)补码的表示形式:上面的二进制形式均为补码形式。
正整数的补码形式比较简单,直接转换成二进制即可,如:
1的二进制补码形式为:0000 0000 0000 0001
2的二进制补码形式为:0000 0000 0000 0010
负整数的补码形式也不难,先将其绝对值按二进制形式转换,再进行取反再加 1 即可,如:
1的二进制补码形式为:0000 0000 0000 0001
取反之后为:1111 1111 1111 1110
再加 1 后为:1111 1111 1111 1111
即为-1的二进制补码形式。
2的二进制补码形式为:0000 0000 0000 0010
取反之后为:1111 1111 1111 1101
再加 1 后为:1111 1111 1111 1110
即为-2的二进制补码形式为。
按相反的步骤转换补码,就可以知道它的十进制的值了。

需要从16进制考虑
x = 1 = 0x00000001
y = -1 = 0xffffffff (负数用补码表示:0x10000001取反加一)
所以:
~x|x = (~x)|x = 0xffffffff = -1 (逆过程转换为原码,也是取反加一)
x^y = 0xfffffffe = -2 (异或)

提供一个小函数
/* getbits: 从位置p得到n位*/
unsigned getbits(unsigned x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}