java 位运算符学习笔记

/*
运算符五 位运算符
左移 << 3<<2 结果 12
右移 >> 3>>2 结果 1
无符号右移 >>> 3>>2 结果 1
与运算 & 6&3 结果 2
或运算 | 6|3 结果 7
异或运算 ^ 6^3 结果 5
取反运算 ~ ~6 结果 -7

位移运算符操作的都是整数数据

& | ^ 是逻辑运算符还是位运算符根据前后变量类型判断
布尔型是逻辑运算,数值型是位运算

位运算针对底层二进制码做操作

左移两位相当于把二进制码后加两个0(不分正负),前面去掉两位
根据二进制转十进制的规律相当于对十进制数乘2的2次幂
在一定范围内(避免将1移动到最高位),每向左移移位相当于乘2(负数也是这个规律)

面试题;以最高效的方式计算 28
使用位移 2<<3 (2
2^3) 或者 8<<1 (8*2^1)

右移两位相当于把二进制码后面去掉两位,前面增加两位,补1还是补0取决原来的正负,正数用00补,负数用11补
无符号右移前面都用0来补位置

*/

import java.util.Scanner;
class BitMoveTest {
	public static void main(String[] args) {
        int i1 = 21;//21 二进制码为 0000 0000 0000 0000 0000 0000 0001 0101 (int为2个字Word4个字节byte32个bit)
		int i2 = 21 << 2;// 左移两位后二进制码为 0000 0000 0000 0000 0000 0000 0101 0100 		
		System.out.println("i1<<2=" + (21 << 2));//输出21*2^2=21*4=84
		System.out.println("i1<<3=" + (21 << 3));//输出21*2^3=21*8=168
		System.out.println("i1<<27=" + (21 << 27));//输出-1476395008, 因为1被最高位(第32位),变为负数
		
		System.out.println("-i1<<2=" + (-21 << 2));//输出-21*2^2=21*4=-84
		System.out.println("-i1<<3=" + (-21 << 3));//输出-21*2^3=21*8=-168
		System.out.println("-i1<<27=" + (-21 << 27));//输出1476395008, 因为1被最高位(第32位),变为负数
	
	    int m = 12;
		int n = 5;
		System.out.println("m & n =" + (m & n));//输出4
		System.out.println("m | n =" + (m | n));//输出13
		System.out.println("m ^ n =" + (m ^ n));//输出9
		System.out.println("m  =" + (m ^ n ^ n));//输出12,m逻辑异或运算两次得到原数值
		System.out.println("~ m =" + (~ m));//输出-13
		System.out.println("m =" + (~ ~ m));//输出12
		/*
		0 0 0 0 1 1 0 0       12
	&	0 0 0 0 0 1 0 1       5     二进制各位做逻辑与运算,1为true 0为false
		0 0 0 0 0 1 0 0       4
 
 		0 0 0 0 1 1 0 0       12
	|	0 0 0 0 0 1 0 1       5     二进制各位做逻辑或运算,1为true 0为false
        0 0 0 0 1 1 0 1       13

		0 0 0 0 1 1 0 0       12
	^	0 0 0 0 0 1 0 1       5     二进制各位做逻辑异或运算,1为true 0为false
		0 0 0 0 1 0 0 1       9

    
	~   0 0 0 0 1 1 0 0       12     二进制包括符号位各位做取反运算,1变为0 ,0变为1
	    1 1 1 1 0 0 1 1       -13    -13的取反运算得到12	


		*/
		//练习:交换两个变量的值
		int num1 = 10;
		int num2 = 20;
        System.out.println("num1 =" + num1 + ",num2 = " + num2);
		//方式1,使用临时变量,常用

		int temp = num1;
		num1 = num2;
		num2 = temp;
		System.out.println("num1 =" + num1 + ",num2 = " + num2);
        
		//方式二,使用加法,不用定义临时变量,节省资源
		//缺点:1,使用相加可能超出变量范围
		//      2,只对数值型变量有用,其它类型不行
		num1 = num1 + num2;
		num2 = num1 - num2;
		num1 = num1 - num2;
		System.out.println("num1 =" + num1 + ",num2 = " + num2);

        //方式三,使用位运算符,利用逻辑异或的性质 m = m ^ n ^ n  n = m ^ n ^ m。使用m^n作为临时变量
		//优点同方式二,且不会超出范围,缺点,只对数值变量适用。

		num1 = num1 ^ num2;
		num2 = num1 ^ num2;
		num1 = num1 ^ num2;
		System.out.println("num1 =" + num1 + ",num2 = " + num2);

		//如何求一个0-255范围内的整数的十六进制,例如60的16进制表示形式为3c
		//方法一,调用类直接求

        String str1 = Integer.toBinaryString(60);
		String str2 = Integer.toHexString(60);
		System.out.println(str1);
		System.out.println(str2);

		//方法二,手写计算,综合利用位移运算,与二进制16进制的换算(二进制数每四位计算一个值为16进制的1位,从右到左)
		
	    Scanner scan = new Scanner(System.in);//创建Scanner实例
	    System.out.println("请输入0-255内的整数");
	    int i3 = scan.nextInt();//从键盘输入需要转换的整数

		int i4 = i3 & 15;//15的二进制是00001111,参与&运算得出的结果就是i3的二进制的后四位
		String a = (i4 > 9)?(char)(i4 -10 + 'A') +"" : i4 + "";//使用三元运算符判断16进制最后那位输出的是数字还是字符
		//因为十六进制中没有10,第10为A, i4-10+'A'就可以输出C,前面也需要强转成char类型才能这样算。后面 + ""是为了转为String型

		int temp1 = i3 >>> 4;// 无符号右移四位后就得到了i3的另外四位
		int i5 = temp1 & 15;//原理同上
		String b = (i5 > 9)?(char)(i5 -10 + 'A') +"" : i5 + "";//原理同上
        if(i3 >= 0 && i3 <=255){
		System.out.println("输入数字的16进制为" + b + "" + a);
		}else{
		System.out.println("输入的数字不在范围内");	
		}
	
	
	
	
	
	
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值