Java位运算

无符号数:所有的为都用来表示直接的01数值, 取值范围[0(2^0)-255(2^7)]。
有符号数:最高位用来表示符号位(0:正数,1:负数),其他位用来表示数值,取值范围[-128(-2^7),127(2^7-1)]。

原码/反码/补码

原码:

正数的原码是二进制原码本身,负数的原码是在正数的原码上高位赋1

整数10原码:0000 1010
整数-10原码:1000 1010

反码:

正数的反码是在正数的原码基础上按位取反,负数的反码是正数的原码基础上按位取反(符号位为1)

整数10反码:0000 1010
整数-10反码:1000 0101

补码:

正数补码和原码一样,负数的补码是在反码的基础上加1

整数10补码:0000 1010
整数-10补码:1000 0110

结论:
①正数的原码/反码/补码都一样
②负数的反码是在原码基础上按位取反
③负数的补码是在负数的反码基础上加1

|(或)

有1为1,例如:

int a = 6;
int b = 5;
a != b;
System.out.println(a);
/*
      2^7  2^6  2^5  2^4  2^3  2^2  2^1  2^0
a      0    0    0    0    0    1    1    0
b      0    0    0    0    0    1    0    1   
|      0    0    0    0    0    1    1    1

result 2^2 + 2^1 + 2^0 = 4 + 2 + 1 = 7
*/

输出结果:

7

&(与)

相同1为1

int a = 6;
int b = 5;
a &= b;
System.out.println(a);
/*
      2^7  2^6  2^5  2^4  2^3  2^2  2^1  2^0
a      0    0    0    0    0    1    1    0
b      0    0    0    0    0    1    0    1   
|      0    0    0    0    0    1    0    0

result 2^2 = 4
*/

输出结果:

4

>>(右移)

右移1位:低位移除1位,高位加上1位

int n = 1888;
System.out.println(n >> 1);

/*
在Java中一个int是占4个字节的,也就是4Byte=4*8=32bit

       符号位 2^30 ........................................................ 2^0
        0     0   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0
>>1     0     0   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0

result 2^9 + 2^8 + 2^7 + 2^5 + 2^4 = 512 + 256 + 128 + 32 + 16 = 944
*/

输出结果:

944

<<(左移)

左移1位:高位移除1位,低位加上1位

int n = 1888;
System.out.println(n << 1);

/*
在Java中一个int是占4个字节的,也就是4Byte=4*8=32bit

       符号位 2^30 ........................................................ 2^0
        0     0   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0
<<1     0     0   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0 0

result 2^11 + 2^10 + 2^9 + 2^7 + 2^6 = 2048 + 1024 + 512 + 125 + 64 = 3776
*/

输出结果:

3776

~(非)

非位运算符的运算需要结合原码/反码/补码一起运算,非是在补码的基础上进行位取反(位为0,结果是1,如果位为1,结果是0)。

int n = 1888;
System.out.println(~n);

/*
在Java中一个int是占4个字节的,也就是4Byte=4*8=32bit

     符号位 2^30 ........................................................ 2^0
原码   0     0   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0
反码   0     0   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0
补码   0     0   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0
~    1     1   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1

result -2^31 + ... + 2^11 + 2^7 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0  = -1889

如果是n=-1888
原码   1     0   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0
反码   1     1   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1
补码   1     1   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 1 0 0 0 0 0
~    0     0   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 1 1 1 1
result 2^10 + 2^9 + 2^8 + 2^6 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 = 1887
*/

^(异或)

两个数值的原码进行比较,相同的0或相同的1结果为0,不相同的则为1。

如果觉得我的文章对你有用,请随意赞赏