
void main()
{
while (1)
{
int a, b;
scanf("%d",&b);
a=~b;
printf("%d\n",a);
}
}
如果输入3,那么结果为-4,如果输入4,结果为-5,这是为什么呢,我用的是32位操作系统。求运算过程
额,这么快,我刚打开这个问题的时候还没有代码呢,发完答案后就已经有正确回答了 - -
--------------------------------------------------------------------------------------
例子呢?
既然没有,我就给你个例子岁清野吧
按位取反是针对二进制位说的。众所周知,二进制是0和1两种,一个整数可以换算成二进制形式,如12 = 1100B,27 = 11011B(B就表示乎喊是按二进制运算)。而~取反操作就是把1变成0,把0变成1。可以理解为 ~12 = 0011B,~27 = 00100B。然而事实上不是这样的。
说到取反,还要设计到的一个东西就是数值的位长。在c语言中,整数有8位(char)、16位(short)、32位(long)等,常用的int在不同的编译环境下,可能是16位也可能是32位,具体的可以用printf("%d", sizeof(int) * 8);的方式确定int的位数。
人工进行整数的位运算之前,首先要确定整数的位长,如TurboC里面的int(16位),转成二进制:27 = 0000 0000 0001 1011 B,要用0在左面补齐16位,然后进行1变0、0变1的取反:1111 1111 1110 0100B,这样的结果再转换回10进制的时候,就涉及到了另一个问题,负数。
二进制整数用左数第一位区分是正数还是负数,当第一位是1的时候,就是负数。正数和负正早数的换算原则是“取反加1”,当你看到一个二进制,按位长的第一个数字是1时,对他进行取反,得到一个正数值,再加1,然后在前面加一个负号。就得到了这个数表示的负数值。
回到刚才我们的例子,~27 = 1111 1111 1110 0100 B,是一个负值,对其取反,就变回了原来的 0000 0000 0001 1011 B 也就是 27,还没完,再加上1,是28,对其加上负号,得到的结果就是-28;也就是说一个正数,按位取反(~运算)后,实际得到的值是 -(这个正数+1)。用同样的方法你可以验证一下 ~12 = -13,~127 = -128。
还有什么问题吗
首先看等号左边
(100) 的二进制表示为: 0110 0100
按位取反的意思就是每一位取反,0变1,1变0
所以:
~100 的二进制表示为:1001 1011
所以等号左边=1001 1011
再看右边
-101. 一旦看到出现负数,那么这个贺慎数一定是按有符号数的规则来表示的。一个二进制数 按位取反并加一以后就可以得到它自己的负数的补码,也就是说:
~x+1=-x
所银销以,我们把101按位取反加一
先取反:
~101=10011010
再加一:
~101+1=10011011=-101
所以等号右边=10011011=左边,所以等号成立。
P.S:补充一句,计算机内存里的逻辑存储位是非常复杂的,我这里即使讲禅搏敬得再清楚也无法保证你完全明白。
一般来说,汇编语言的书的开头部分会详细讲解这部分知识以服务于汇编语言,请参阅之。
b=3; //00000000 00000000 00000000 00000011
~b; //11111111 11111111 11111111 11111100 符号位变为1 表示是负数
a = b; //负数耐镇在内存中是以补码形式存在的,所以现在 取昌唯粗反+1
//山世10000000 00000000 00000000 00000100 -4
b=4; //00000000 00000000 00000000 00000100
~b; //11111111 11111111 11111111 11111011
a = b; //10000000 00000000 00000000 00000101 -5
a=~b; 因为-b=~b+1(补码原理) ,那么 ~b=-b-1
所以 a=~b就是 a=-b-1