这个问题让我很苦恼,我三次面试都遇到了这个问题。
1、二进制怎么写
2、实现两个数交换不用中间变量
-
首先须知:
1、一个字节是8位。所以为什么1个字节的范围是-128到127
2、二进制怎么写。8421法则,逢2进1(自己品吧) -
注意:
1、所有的二进制运算都是用补码运算
2、正数的补码是它本身
3、负数的补码是它本身取反再加1.
4、负数本身就是补码减一再取反
5、注意负数和补码的转换符号位是不变的!其他位取反 -
符号运算
1、~取反
2、&与(都为1才为1)
3、|或(有一个为1就可以了为1了)
4、 ^异或 (需要不同才为1)
5、<<和>> 算术右移和左移 (移多少位就补多少,正数补0,负数补1)
6、>>>逻辑右移(和算术右移的唯一区别就是不管正数还是负数都补0) -
例子:
1、~5:(以两个字节来写吧)
二进制:0000 0000 0000 0101
5的补码:正数就是它本身,然后取反运算
取反: 1111 1111 1111 1010(负数的补码是负数取反再加1,负数本身就是补码减1取反咯,倒过来自己品)
负数本身:1000 0000 0000 0110 —>-6
2、-10>>2 (右移)
二进制:1000 0000 0000 1010
补码: 1111 1111 1111 0110
右移2位:11 1111 1111 1101
负数补1:1111 1111 1111 1101 (这是负数的补码要转为原码
原码: 1000 0000 0000 0011 —>-3
3、-11>>>2 (逻辑右移)
二进制:1000 0000 0000 1011
补码:1111 1111 1111 0101
右移2位:1111 1111 1111 01
补0(正负都是补0)0011 1111 1111 1101
4、剩下的异或、与、或运算都是这样
一定要注意:
负数的补码是取反再加1
由补码转为负数就是:减1再取反
5、实现两个数交换,不用中间变量,int a=3; int b=5;
方法一:
a=a+b; (a此时为8)
b=a-b; (b此时为8-5=3)
a=a-b; (a此时为8-3=5)
方法二:(用二进制异或:不同才为1)
①a=a^b;
a:0011
b:0101
a^b:0110 (此时a为6)
②b=a^b; (0110异或0101 此时b为3)
③a=a^b; (0110异或0011 此时a为5)