位运算的基本运算详解

在处理整形数值时,可以直接对组成整形数值的各个位进行操作。

  1. &(与)
  2. |(或)
  3. ^(异或)
  4. ~(非)
  5. >>和<<运算符将二进制位进行右移和左移操作
  6. >>>运算符将用0填充高位;>>运算符用符号位填充高位,没有<<<运算符
  7. 对于int型,1<<35和1<<3是相同的(取模32),而左边的操作数是long型时需要对右侧操作数取模64
  8. &都为1时才为1,| 有一个为1就为1,异或(^)俩者不一样的时候为1.

测试代码:

int a=11;
		int b=12;
		System.out.println(Integer.toBinaryString(a));
		System.out.println(Integer.toBinaryString(b));
		int c=a&b;
		System.out.println(Integer.toBinaryString(c));
		int d=a|b;
		System.out.println(Integer.toBinaryString(d));
		int e=a^b;
		System.out.println(Integer.toBinaryString(e));
		int f=a>>1;
		System.out.println(Integer.toBinaryString(f));
		int g=a<<1;
		System.out.println(Integer.toBinaryString(g));
		int h=a>>>1;
		System.out.println(Integer.toBinaryString(h));

 

判断奇偶数:

如果一个数和1按位与是1,说明是奇数,否则是偶数;

int a=11;
		int b=a&1;
		System.out.println(b);

1-1000个数这一千个数放在含有1001个元素的数组中,只有唯一一个元素重复,其他只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助空间,能否设计一个算法实现?

提示:使用异或运算

思路:将数组中除了俩个重复的数字之外,其他的数字通过异或运算都消掉,创建一个数组是没有重复的数值,和原数组异或

具体代码如下:

public class Mains{
	public static void swap(int a[],int i,int j){
		int temp=a[i];
		a[i]=a[j];
		a[j]=temp;
	}
	public static void main(String[] args) {
		int max=1000;
		int a[]=new int[max+1];
		for (int i = 0; i < a.length-1; i++) {
			a[i]=i+1;
		}
		int number=(int)(Math.random()*max)+1;
		int index=(int)(Math.random()*max);
		a[a.length-1]=number;
		System.out.println("随机数:"+number);
		System.out.println("随机下标:"+index);
		swap(a,index,a.length-1);
		System.out.println(Arrays.toString(a));
		int x=0;
		for (int i = 1; i <= max; i++) {
			x=x^i;
		}
		for (int i = 0; i < a.length; i++) {
			x=x^a[i];
		}
		System.out.println(x);
	}
}

解法二:运用数组下标的方法,把每个数字都变成下标,内容装数字出现的次数

int b[]=new int[max+1];
		for (int i = 0; i < a.length; i++) {
			b[a[i]]++;
		}
		for (int i = 0; i < b.length; i++) {
			if(b[i]==2){
				System.out.println(i);
			}
		}

题二:一个数组里面除了某种数字出现奇数次以外,其他种数字都出现了偶数次,请在程序中找到这个出现奇次的数字。

提示:根据异或偶数次相消原理

具体代码如下:

import java.util.Arrays;

public class Mains{
	public static void swap(int a[],int i,int j){
		int temp=a[i];
		a[i]=a[j];
		a[j]=temp;
	}
	public static void main(String[] args) {
		int a[]=new int[11];
		int number=(int)(Math.random()*10)+1;
		int count=0;
		for (int i = 0; i < a.length; i++) {
			if(count==2){
				number=(int)(Math.random()*10)+1;
				count=0;
			}
			a[i]=number;
			count++;
		}
		System.out.println(Arrays.toString(a));
		int x=0;
		for (int i = 0; i < a.length; i++) {
			x=x^a[i];
		}
		System.out.println(x);
	}
}

题三:一个整数二进制中1的个数。

例如:100二进制是1100100其中1的个数是3

方法一:使用位运算与,把二进制中每一位都和1进行与运算如果结果和1<<i位相同那么说明这个位上的数是1

具体代码如下:

int a=100;
		int count2=0;
		for (int i = 0; i < 32; i++) {
			if((a&(1<<i))==(1<<i)){
				count2++;
			}
		}
		System.out.println(count2);

方法二:把整数的二进制通过字符串形式表现出来,每个字符比较,如果该字符是‘1’,那么计数加一。

具体代码如下:

int a=100;
		String str=Integer.toBinaryString(a);
		StringBuffer sb=new StringBuffer(str);
		System.out.println(sb);
		int count=0;
		for (int i = 0; i < sb.length(); i++) {
			if(sb.charAt(i)=='1'){
				count++;
			}
		}
		System.out.println(count);

题四:如何判断一个整数是不是2的整数次方:

提示:2的整数次方转化为二进制是只有某个位上是一,其余位置上都是0,可以将问题转化为是否只有一个1

具体代码如下:

import java.util.Arrays;

public class Mains{
	public static void main(String[] args) {
		int a=32;
		System.out.println(Integer.toBinaryString(a));
		int x=0;
                //方法一
		for (int i = 0; i <32; i++) {
			if((a&(1<<i))==(1<<i)){
				x++;
			}
		}
		if(x==1){
			System.out.println("是2的整数次方");
		}else{
			System.out.println("不是2的整数次方");
		}
		//方法二
		if(((a-1)&a)==0){
			System.out.println("是2的整数次方");
		}else{
			System.out.println("不是2的整数次方");
		}
	}
}

题五:如何将一个整数位的二进制数的奇数位和偶数位互换。

提示:1和二进制位上数字&是保留,0和二进制位上数字&是消除。所以可以将数字和01010101&保留奇数位上数字,和10101010&保留偶数位上数字,最后将第一个数字左移,将第二个数字右移,把俩个数字异或(不同的为1)一下,就能将奇数位和偶数位互换。

具体代码如下:

public class Mains{
	public static void main(String[] args) {
		int a=110;
		int oushu=0xaaaaaaaa;
		int jishu=0x55555555;
		System.out.println(Integer.toBinaryString(a));
		int b=((a&0xaaaaaaaa)>>1)^((a&0x55555555)<<1);
		System.out.println(Integer.toBinaryString(b));
	}
}

题六:用二进制表示0到1之间的实数,类型为double打印它的二进制表示,如果该数字无法精确地用32位以内的二进制表示,则打印“ERROR”

提示:计算方法乘2取成整:

具体代码:

public class Mains{
	public static void main(String[] args) {
		double a=0.625;
		int count=0;
		StringBuffer sb=new StringBuffer();
		while(a!=0.0){
			a=a*2;
			int b=(int)a;
			sb.append(b);
			a=a-b;
			if(count>34){
				System.out.println("ERROR");
				break;
			}
			count++;
		}
		if(count<=34){
			int c=Integer.valueOf(new String(sb));
			System.out.println(c);
		}
	}
}

喜欢的记得点个关注哟

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值