要了解取反运算,首先需要知到一下几个概念:
1计算机中存储整数都是用的补码, 取反运算也是对补码进行取反。(当然一定要清楚,虽然我们一只都说求补码需对原码取反后加1,但是此取反和标题的取反运算有些不一样!!!取否者会混淆!!!)
标题的取反运算~是需要对计算机存储的补码的所有位进行取反。
求补码中取反加1是需要保留符号位的。这个取反代表求反码
否者总是纠结为什么负数取反的时候,不保留符号位。我们一定要记住“~”这个玩意儿对一个数进行操作的时候,是对其补码的所有位(包括符号位)进行取反。我们的目的在于要对这个数进行取反,而不是对这个数进行求反码或者求补码运算!!!
2.所有的数字大小都是根据原码的大小计算的,最终我们在JAVA程序运行结果框中看到的数值的大小,就是原码的大小。
3.正整数的反码,补码和原码相同,负整数的反码是除了符号位以外取反,负数的补码为反码+1
4.对补码再求补码即是原码
5.java中存储的数据的最高位为符号位,最高位为0,代表正数;最高位为1,代表负数。
---------------------------------------------------------------------------------------------------------------------------------
例如:
int a=10;
system.out.println(a);
当输出a时,显而易见,结果框中肯定显示10。
这个10,是我们能看见的,且是十进制数,将其转换为二进制原码为:
0000 0000 0000 0000 0000 0000 0000 1010 (int型有32位)
原码这么大一长串的值是和10相等的,这一点我们是没有异议的。
当然原码只能算是我们自己打草稿转换出来的数,而并非计算机存储的数,计算机只会存储10的补码。
当然,10是一个正数,所以,其原码、反码、补码都相同为:
0000 0000 0000 0000 0000 0000 0000 1010
对10进行取反运算 ~10,就相当于对10的补码的所有位进行取反,从而得到x的补码
设x=~10 (x为JAVA程序运行结果框中我们能看见的十进制数值的大小)
将0000 0000 0000 0000 0000 0000 0000 1010 取反后得
1111 1111 1111 1111 1111 1111 1111 0101
这串数字便是我们要求的x的补码,而并非和x值等大的原码。看最高位为1,所以x值为负数。
需要对其补码求补码,来的到x的原码。
对1111 1111 1111 1111 1111 1111 1111 0101求补码得(符号位不变,求其反码后加1)
补码的反码:1000 0000 0000 0000 0000 0000 0000 1010
补码的补码(即x的原码):1000 0000 0000 0000 0000 0000 0000 1011
将其转换为十进制后,即为x的值,其中最高位为1,代表负号-
其位的结果诶8+2+1=11
于是最终结果为-11
所以x的值,也就是我们JAVA运行结果框中展示的值就为-11
---------------------------------------------------------------------------------------------------------------------------------
接下来我们举一个负数取反的例子,对-10取反
设 int y=~(-10);
-10的 原码为:1000 0000 0000 0000 0000 0000 0000 1010 (最高位的1为负数)
对-10取反,就相当于对-10的补码取反
-10求补码:
求反码得:1111 1111 1111 1111 1111 1111 1111 0101(符号位保留,其余取反)
补码为:1111 1111 1111 1111 1111 1111 1111 0110(反码加1)
这样我们就得到了-10的补码了,但是我们的目的是对-10进行取反,得到真正的y的值。
所以对-10取反,相当于对-10的补码的所有位进行取反,得到y的补码。
对-10的补码取反得:0000 0000 0000 0000 0000 0000 0000 1001(这个便是y的补码)
看其最高位为0,所以其为整数,整数原码、反码、补码相同,所以其原码也是:
0000 0000 0000 0000 0000 0000 0000 1001
最终将原码转换为十进制的到y的值。最高位0代表+,可以不显示。
y=8+1=9
---------------------------------------------------------------------------------------------------------------------------------总而言之,
进行取反运算时(~)记住如下步骤:
1,如果是对 x1 进行取反 得x2
A. 求x1的补码。
(这个过程要保留符号位)且要记住正数补码、反码、原码相同。负数按保留符号位,其他位按位取反再加1正常运算即可。
B. 对x1补码的全部位进行取反
(这个过程符号位也要取反) 这个过程才是真正的“~”取反运算
之前每次算到B步骤,还总是在想,怎么突然不保留符号位了 *-*||
从而得到x2的补码。
C.求x2。
对B中得到x2的补码求补码,从而得到x2的原码,最后转换为十进制的x2。(这个过程符号位也要保留)
希望自己,也希望大家不要在搞混了。