java 位运算

public class BitOperate {

	public static void bitCalc() {
		byte a = 12,b=10;
		byte c = -12,d=-10;
		
		/**
		 * 1、按位与   & 
		 * (AND)
		 * 运算方法:当两边操作数的位同时为1时,结果为1,否则为0
		 * 
		 * 注意:符号位也会参与运算
		 */
		// 12二进制表示(1100),10二机制(1010)
		System.out.println("正数与运算:"+(a&b));  //1100&1010=1000 == 8 
		//注意:负数计算机用补码表示:
		// -12:11110100, -10:11110110
		System.out.println("负数与运算:"+(c&d));  //(11110100)补=(10001100)原 == -12
		//
		System.out.println("正负数与运算:"+(a&d));//00001100&11110110 = 00000100 == 4 
		System.out.println();
		
		/**
		 * 2、按位或  |
		 * (OR)
		 * 运算方法:当两边操作数的位有一边为1时,结果为1,否则为0
		 * 
		 */
		System.out.println("正数或运算:"+(a|b)); //1100|1010=1110 == 14
		// -12:11110100, -10:11110110
		System.out.println("负数或运算:"+(c|d)); //(11110110)补=(10001010)原 == -10
		// 12:00001100, -10:11110110
		System.out.println("正负数或运算:"+(a|d));  //(11111110)补=(10000010)原 == -2
		System.out.println();
		
		/**
		 * 3、按位非  ~  
		 * (NOT)
		 * 运算方法:操作数的位0变1,1变0
		 * 
		 */
		// 12: 00001100
		System.out.println("正数非运算:"+ (~a)); //11110011=(10001101)原 == -13
		// -12: 11110100
		System.out.println("负数非运算:"+ (~c)); //00001011 == 11
		System.out.println();

		/**
		 * 4、按位异或  ^
		 * (XOR)
		 * 运算方法: 对比每个数位上的0或1如果相同,那么结果就取0,如果不同就取1
		 *  
		 */
		// 12: 00001100), 10: 00001010)
		System.out.println("正数异或运算:"+ (a^b)); //000000110 == 6
		// -12:11110100, -10:11110110
		System.out.println("负数异或运算:"+(c^d)); //00000010 == 2
		// 12:00001100, -10:11110110
		System.out.println("正负数异或运算:"+(a^d));  //(11111010)补=(10000110)原 == -6
		System.out.println("--------------------------------------------");
		
		
		/**
		 * 移位运算
		 * 
		 * 概念:
		 * 		移位运算符就是在二进制的基础上对数字进行平移。
		 * 
		 * 分类:
		 * 		按照平移的方向和填充数字的规则分为三种:<<(左移)、>>(带符号右移)和>>>(无符号右移)。
                * 
		 * 运算方式:
		 * 		在移位运算时,byte、short和char类型移位后的结果会变成int类型,
		 * 对于byte、short、char和int进行移位时,规定实际移动的次数是移动次数和32的余数,
		 * 也就是移位33次和移位1次得到的结果相同。
         *     移动long型的数值时,规定实际移动的次数是移动次数和64的余数,
         * 也就是移动66次和移动2次得到的结果相同。
         *
		 * 
		 */
		 
		/**
		 * 5、左移  << 
		 *  
		 * 运算方法: 
		 * 		按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
		 * 
		 * 数学意义:
  		 *	 	在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。
  		 *
		 */
		//before: 0000 0000 0000 0000 0000 0000 0000 1100
		//after:  0000 0000 0000 0000 0000 0000 0011 0000  == 48
		System.out.println("正数左移:"+(a<<2));  //a*2*2 = 48
		System.out.println("负数左移:"+(c<<2));  //c*2*2 = -48
		//数字溢出的情况:
		//12
		//before: 0000 0000 0000 0000 0000 0000 0000 1100
		//<<28 after : 1100 0000 0000 0000 0000 0000 0000 0000
		//<<29 after : 1000 0000 0000 0000 0000 0000 0000 0000  -0补码代表最小负数2的31次方就是-2147483648
		System.out.println("正数左移溢出:"+(a<<28));  //-1073741824
		System.out.println("正数左移溢出:"+(a<<29));  //-2147483648
		//-12
		//before: 1111 1111 1111 1111 1111 1111 1111 0100
		//<<28after : 0100 0000 0000 0000 0000 0000 0000 0000
		//<<28after : 1000 0000 0000 0000 0000 0000 0000 0000
		System.out.println("负数左移溢出:"+(c<<28));  //1073741824
		System.out.println("负数左移溢出:"+(c<<29));  //-2147483648
		System.out.println();
		
		/**
		 * 5、有符号右移  >> 
		 *  
		 * 运算方法: 
		 * 		按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1。
		 * 
		 * 数学意义:
  		 *	 	在数字没有溢出的前提下,右移一位相当于除2,右移n位相当于除以2的n次方。
  		 *
		 */
		//10 : 0000 0000 0000 0000 0000 0000 0000 1010
		//>>2after:  0000 0000 0000 0000 0000 0000 0000 0010 
		System.out.println("正数有符号右移:"+(b>>2));  //a/2*2 = 2
		//-10:1111 1111 1111 1111 1111 1111 1111 0110
		//>>2after: 111111 1111 1111 1111 1111 1111 1111 1101
		System.out.println("负数有符号右移:"+(d>>2));  //-3
		System.out.println();
		
		/**
		 * 5、无符号右移  >>> 
		 *  
		 * 运算方法: 
		 * 		按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补零。
		 *      对于正数来说和带符号右移相同,对于负数来说不同。
		 * 
		 * 其他结构和>>相似。
  		 *
		 */
		//10 : 0000 0000 0000 0000 0000 0000 0000 1010
		//>>>2after:  0000 0000 0000 0000 0000 0000 0000 0010 
		System.out.println("正数无符号右移:"+(b>>>2));  // 正数的情况与>>相同
		//-10:1111 1111 1111 1111 1111 1111 1111 0110
		//>>>2after: 001111 1111 1111 1111 1111 1111 1111 1101
		System.out.println("负数无符号右移:"+(d>>>2));  //负数高位补0:1073741821
	}

	public static void main(String[] args) {
		BitOperate.bitCalc();
	}
}

运算结果:

正数与运算:8
负数与运算:-12
正负数与运算:4

正数或运算:14
负数或运算:-10
正负数或运算:-2

正数非运算:-13
负数非运算:11

正数异或运算:6
负数异或运算:2
正负数异或运算:-6
--------------------------------------------
正数左移:48
负数左移:-48

正数左移溢出:-1073741824
正数左移溢出:-2147483648
负数左移溢出:1073741824
负数左移溢出:-2147483648

正数有符号右移:2
负数有符号右移:-3

正数无符号右移:2
负数无符号右移:1073741821
/**
	 * byte、short类型左移
	 * 
	 * 会自动转换为int类型进行右移
	 */
	public static void bitShift() {
		byte a = 64, b; 
		int i; 
		i = a << 2; 
		b = (byte) (a << 2); 
		System.out.println("Original value of a: " + a); 
		System.out.println("i (int): " + i + "----- b(byte): " + b); 
	}

结果:

Original value of a: 64
i (int): 256----- b(byte): 0


移位运算的总结:

1.对于左移运算:

          1>每左移一个位,高阶位都被移出(并且丢弃),并用0填充右边。这意味着当左移的运算数是int 类型时,每移动1位,它的第31位就要被移出并且丢弃;当左移的运算数是long 类型时,每移动1位它的第63位就要被移出并且丢弃。

         2>左移都可以使原来的操作数翻倍,程序员们经常使用这个办法来进行快速的2 的乘法。但是你要小心,如果你将1移进高阶位(31或63位),那么该值将变为负值。

         3>在对byte 和short类型的值进行移位运算时 , Java将自动把这些类型扩大为 int 型,而且,移位后的值也是int 型;如果左移不超过31位,原来对应各位的值不会丢弃。但是,如果你对一个负的byte 或者short类型的值进行移位运算,它被扩大为int 型后,它的符号也被扩展,结果的高位就会被1填充。因此,为了得到正确的结果,你就要舍弃得到结果的高位。这样做的最简单办法是将移位运算的结果再转换成byte 型 。

2.对于右移运算:每右移一次,就相当于将该值除以2并且舍弃了余数。你可以利用这个特点将一个整数进行快速的2的除法。当然,你一定要确保你不会将该数原有的任何一位移出。

3.无符号右移(>>>)与右移的区别:每一次右移,>>运算符总是自动地用它的先前最高位的内容补它的最高位。这样做保留了原值的符号。而无符号移动总是在高位(最左边)补0。

4.与C、C++不同,Java中没有无符号型整数,而且明确规定了整型和浮点型数据所占的内存字节数,这样就保证了安全性、鲁棒性和平台无关性。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值