位运算符:
&(“与”)、|(“或”)、^(“异或”)、~(“非”)
这些运算符只能作用于整型操作数。有符号的或无符号的。
(&)经常用于屏蔽某些二进制位,
两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段。
public class data13{
public static void main(String[] args){
int a=129;
int b=128;
System.out.println("a 和b 与的结果是:"+(a&b));
}
}
运行结果
a 和b 与的结果是:128
下面分析这个程序:
“a”的值是129,转换成二进制就是10000001,而“b”的值是128,转换成二进制就是10000000。根据与运算符的运算规律,只有两个位都是1,结果才是1,可以知道结果就是10000000,即128。
( | )常用于将某些位置为1。
两个位只要有一个为1,那么结果就是1,否则就为0,下面看一个简单的例子。
public class data14{
public static void main(String[] args){
int a=129;
int b=128;
System.out.println("a 和b 或的结果是:"+(a|b));
}
}
运行结果
a 和b 或的结果是:129
下面分析这个程序段:
a 的值是129,转换成二进制就是10000001,而b 的值是128,转换成二进制就是10000000,根据或运算符的运算规律,只有两个位有一个是1,结果才是1,可以知道结果就是10000001,即129。
( ^ )当两个操作数的对应位不同时将该位设置为1。
两个操作数的位中,相同则结果为0,不同则结果为1。下面看一个简单的例子。
public class data16{
public static void main(String[] args){
int a=15;
int b=2;
System.out.println("a 与 b 异或的结果是:"+(a^b));
}
}
运行结果
a 与 b 异或的结果是:13
分析上面的程序段:a 的值是15,转换成二进制为1111,而b 的值是2,转换成二进制为0010,根据异或的运算规律,可以得出其结果为1101 即13。
~求整数的二进制反码,~0可获得与机器字长无关的一串1。
如果位为0,结果是1,如果位为1,结果是0,下面看一个简单例子。
public class data15{
public static void main(String[] args){
int a=2;
System.out.println("a 非的结果是:"+(~a));
}
}
位移动运算符:
1、<<:左移 左边最高位丢弃,右边补齐0;
左移的规则只记住一点:丢弃最高位,0补最低位;
如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。
它的通用格式如下所示:
value << num
num 指定要移位值value 移动的位数。
//<< 把<<左边的数据乘以2的移动次幂
//3*2^2 = 3*4 = 12;
System.out.println(3 << 2);
例如:3 <<2(3为int型)
1)把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,
2)把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,
3)在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,
转换为十进制是12。
移动的位数超过了该类型的最大位数, 如果移进高阶位(31或63位),那么该值将变为负值。
右移的规则只记住一点:符号位不变,左边补上符号位 。
按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1
当右移的运算数是byte 和short类型时,将自动把这些类型扩大为 int 型。
例如,如果要移走的值为负数,每一次右移都在左边补1,如果要移走的值为正数,每一次右移都在左边补0,这叫做符号位扩展(保留符号位)(sign extension ),在进行右移 。操作时用来保持负数的符号。
//<< 把<<左边的数据乘以2的移动次幂
//3*2^2 = 3*4 = 12;
System.out.println(3 << 2);
计算出24的二进制:11000
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111
补码:11111111 11111111 11111111 11101000
11111111 11111111 11111111 11101000
1111111111 11111111 11111111 111010(00) 补码
补码:1111111111 11111111 11111111 111010
反码:1111111111 11111111 11111111 111001
原码:1000000000 00000000 00000000 000110
结果:-6
3、>>>:无符号右移 无论最高位是0还是1,左边补齐0;
无符号右移运算符>>>
它的通用格式如下所示:
value >>> num
num 指定要移位值value 移动的位数。
无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位。
无符号右移运算符>>> 只是对32位和64位的值有意义。
计算出24的二进制:11000
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111
补码:11111111 11111111 11111111 11101000
11111111 11111111 11111111 11101000
0011111111 11111111 11111111 111010(00)
结果:6
位运算的部分代码解释:
package com.zf.binary;
public class Test1 {
public static void main(String[] args) {
/* 符号为:最高位同时表示图号,0为正数,1为负数 */
/*
1、二进制转换为十进制
二进制转换为10进制的规律为: 每位的值 * 2的(当前位-1次方)
例如:
00000001 = 0 * 2^7 + 0 * 2^6 + 0 * 2^5 + 0 * 2^4 + 0 * 2^3 + 0 * 2^2 + 0 * 2^1 + 1 * 2^0 = 1
00000010 = 0 * 2^7 + 0 * 2^6 + 0 * 2^5 + 0 * 2^4 + 0 * 2^3 + 0 * 2^2 + 1 * 2^1 + 0 * 2^0 = 2
2、二进制的符号位:
最高位表示符号位,0表示正数 , 1表示负数
3、将二进制负数转换为十进制:先对该二进制数取反,然后加1,再转换为十进制,然后在前面加上负号
例如: 10101011 最高位为1,所以为负数
第一步:取反: 01010100
第二步:加1 : 01010101
第三步:转换为10进制:85
第四步:加上负号: -85
所以 10101011 转换为十进制为 -85
4、将十进制负数转换为二进制:先得到该十进制负数的绝对值,然后转换为二进制,然后将该二进制取反,然后加1
例如:-85
第一步:得到绝对值 85
第二步:转换为二进制:01010101
第二步:取反: 10101010
第三步:加1: 10101011
所以,-85转换为二进制为 10101011
*/
/*
~ ‘非’ 运算符是将目标数的进制去反,即0变成1 ,1变成0
2的二进制码为 00000010 , 它取反为11111101 ,可见取反后结果为负数(二进制负数转换为十进制的步骤为:将二进制去反,然后+1)
将 11111101 转换为10进制 ,第一步去反 得到 00000010 然后 加1 得到 00000011 ,得到的结果为3 ,然后在前面加上负号就可以了
所以结果为-3
*/
System.out.println(~2);
/*
^ 异或 ,计算方式为:两个二进制数的位相同则为0 不同则为1
23转换为二进制为:00010111
12转换为二进制为:00001100
计算结果为:00011011 = 27
*/
System.out.println(23 ^ 12);
/*
& 按位与 ,计算方式为:两个二进制数的位都为1则为1 ,否则为0
1的二进制为 :00000001
2的二进制为 :00000010
结果为 :00000000 = 0
*/
System.out.println(1&2);
/*
| 按位或 ,计算方式为:两个二进制位有一个为1就为1,否者为0
5 的二进制为:00000101
6 的二进制为:00000110
结果为:00000111 = 7
*/
System.out.println( 5 | 6);
/*
>> 有符号右移位 ,符号左边表示要被移位的数,右边表示需要移的位数,结果为正数则在左边补0,否则补1
3 的二进制为:00000010
向右移动1位:00000001 = 1
*/
System.out.println(3 >> 1);
}
}