算法很美1.1 位运算

目录

位运算[简述]

位运算的种类

位运算的怪操作

1.判断奇偶数

2.获取一个数字的第n位二进制数是0还是1

3.交换两个整数变量的值

4.求整数的绝对值

小结


位运算[简述]

        位运算常常针对整数类型来进行操作

        意味着我们可以直接对整形的具体某一位来进行相关的操作。

        [计算机底层是通过2进制来进行存储和操作]

位运算的种类

与(&) 或(|)非(~)异或(^)左移(<<)

右移(>>)【用符号位填充高位】

右移(>>>)【用0填充高位】                                 

特别注意不存在 <<<

位运算的怪操作

1.判断奇偶数

根据底层2进制的规律-------->二进制转换为10进制都是2^{n}的累加和

例如:8=1*2^{3}+0*2^{2}+0*2^{1}+0*2^{0}

从而得出规律该数字构成的累加和 是否存在2^{0}

即最低位为0则说明该数字为偶数,最低位为1则说明该数字为奇数

核心操作:将该数字与1相与     &1

结果为0则说明该数字为偶数,最低位为1则说明该数字为奇数

public class Main {
	public static void main(String[] args) {
		int x=8;
		System.out.println(x+"是"+(((x&1)==1)?"奇数":"偶数"));//8是偶数
        int y=1;
		System.out.println(y+"是"+(((y&1)==1)?"奇数":"偶数"));//1是奇数
	}
}

2.获取一个数字的第n位二进制数是0还是1

前言已经说过,我们可以直接对某一个整数的具体某一位来进行操作

思路1:1移位到第n位置--与其相与--然后将结果再右移到最低位得到数字

  0则说明该位置为0            若为1则说明该位置为1

思路2:现将要判断的数字的第n位右移至最低位-----然后再与1相与得到数字

  若为0则说明该位置为0            若为1则说明该位置为1

例子:问8的第四位为1还是0               

                8=1*2^{3}+0*2^{2}+0*2^{1}+0*2^{0}

public class Main {
	public static void main(String[] args) {
		int x=8;
		//8二进制形式为:1000
		System.out.println(x+"二进制形式为:"+Integer.toString(x,2));
		//法1
		System.out.println(x+"的第4位的二进制数为"+((x&(1<<3))>>3));//1
		//法2
		System.out.println(x+"的第4位的二进制数为"+((x>>3)&1));//1
	}
}

3.交换两个整数变量的值

 异或的需要特别注意的公式:

  • A^A=0;
  • A^B^B^B^B……=A, 
  • A^0=A

交换两个变量数值我们常用的是空瓶子法 即如下:

        int a=6;
		int b=1;
		int temp;
		temp=a;
		a=b;
		b=temp;

而此处我们要讲的是通过位运算来解决这个问题

我们用a0表示a之前的数值 a1表示a^b

b0表示b之前的数值   b1表示a0

根据异或的特点  下列代码可解释为:

  • a1=a0^b0
  • b=a1^b=a0^b0^b0=a0;
  • a=a1^b1=a0^b0^a0=b0;
public class Main {
	public static void main(String[] args) {
		int a=6;
		int b=3;
		a=a^b;
		b=a^b;
		a=a^b;
		System.out.println(a);//3
		System.out.println(b);//6
	}
}

4.求整数的绝对值

思路:

我们知道int类型的整数有32位

最高位是不存储数值的 最高位代表的是符号位 正数为0 负数为1[即真正存储数据的位数只有31位]

下来我们来进行举例说明  PS(只作了解即可  对于求绝对值我们可以直接调用Math.abs()的方法)

知识回顾:

  1. >>是带符号位的右移  向右移动一位其高位用符号位填充
  2. >>>是不带符号位的右移  向右移动一位其高位用0填充

举例说明:存在int x

x>>31若x为正数 则会出现32位全为0    ------->10进制数对应为0

x>>31若x为负数 则会出现32位全为1   ------->10进制数对应为-1

核心代码:x^(x>>31)+(x>>>31)

x为正数:x^0=x+0=x

x为负数:x^-1[取反]  取反后+1为绝对值      此处涉及到补码 反码 原码的知识

简单一提:

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

public class Main {
	public static void main(String[] args) {
		int a=-6;
		System.out.println((a^(a>>31))+(a>>>31));//6
	}
}

小结

对于位运算更多涉及到对于计算机底层二进制的了解,以及对于原码、补码、反码的知识的理解和运用,对于这部分知识可以参考:

原码、反码、补码知识详细讲解

终于写完了哈哈哈哈

ps:第一次写文章,作者水平很菜,若有错误欢迎评论指出 谢谢大家。

以及对于文章的排版 美化也存在一定问题 也在不断学习当中 敬请谅解


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值