复习笔记5 位运算符 以及位移超出整数类型边界的回滚原理

本文详细解析Java中位运算符的工作机制,包括左移运算符的使用与原理,通过实例演示如何利用位移操作进行快速计算,同时揭示左移运算符在不同位移值下的行为特性,以及其与乘法运算的关系和效率比较。文章还探讨了位移操作的有效范围,引入模运算和掩码的概念来优化位移操作,最终提供了一种高效计算位移结果的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class Test6
{
	public static void main(String[] args)
	{
		//位运算符
		// << 左移运算符
		//5 的二进制是 0000 0101
		//左移一位的话0000 1010
		//5 左移一位是10,是不是相当于5*2
		System.out.println(5 << 1);
		//3左移一位正好是6
		System.out.println(3 << 1);
		//3左移两位是12,也就是*4
		System.out.println(3 << 2);
		//对比下,其实这个表达式跟上方的位移的结果
		//是一致的,运算效率上却要慢很多,这里只是
		//描述下,左移相当于乘上2的几次幂
		System.out.println((int)(3 * Math.pow(2, 2)));
		//下边发现左移0和32还是5,为什么呢?
		System.out.println(5 << 0);
		System.out.println(5 << 32);
		//木哈哈,这个绝对大杀器,为什么-1是31,-2是30?
		System.out.println(5 << -1);
		System.out.println("====================================>");
		
		//打印一下x的位移情况,发现左移32位,x还是
		//原值,为什么会这样?
		//分析下最后几行,发现,并不是逐位补位的,
		//最后一行的像突然插进去的一样。
		int x = 7;
		for (int shift = 0; shift <= 32; shift++)
        {
	        System.out.println(getIntegerToBinary(x << shift));
        }
		System.out.println("====================================>");
		//到这里可以看见,貌似从32开始,又开始像0-31
		//那样子逐位位移了,到第64次的时候又会在继续
		//这看起来是不是像模运算呢?
		//其实这不难理解,比如没有这个现象的话,咱就单
		//说位移,32位之后就都是0了吧,显然没有意义,
		//对于一个int的有效位移次数仅是0-31
		System.out.println(getIntegerToBinary(x << 33));
		System.out.println("====================================>");
		//事实证明,猜想是对的,但问题是,真的是这样?
		//模运算是很慢的,如果真是这样,位移操作还能比
		//乘法快?
		for (int shift = 0; shift <= 32; shift++)
        {
	        System.out.println(getIntegerToBinary(x << shift % 32));
        }
		System.out.println("====================================>");
		//既然有效位移次数是0-31,那么31的2进制是什么?
		//是11111五个一,咱是不是只需要拿到位移次数的
		//低五位就可以了?你可以打印下0-64的2进制,看看
		//后5位是什么情况
		//如果这个实在难以理解,你就当成是32进制,每次取
		//这个数的32进制的个位数
		for (int shift = 0, mask = 0x0000001f; shift <= 32; shift++)
        {
	        System.out.println(getIntegerToBinary(x << (shift & mask)));
        }
		System.out.println("====================================>");
		//这个眼熟不?如果 % 的方式是对的?左移-1位你怎么
		//解释?当然你理解成0相当于32,-1相当于31这是可以
		//但是,你怎么解释-1和31的关系?有什么证据?
		//总不能说-1%32是31,那还不让人笑掉大牙?
		//-1 & 0x0000001f是多少?取后五位正好是31
		System.out.println(getIntegerToBinary(x << (-1 % 32)));
		System.out.println(getIntegerToBinary(x << (-1 & 0x0000001f)));
		//将上边的两行化简,最后就是这样的了,结果一样,那
		//也就是说-1被处理,跟%没有一毛钱关系,问题发生在
		//-1怎么变成31,呵呵,已经很明显了吧?
		System.out.println(getIntegerToBinary(x << -1));
		System.out.println(getIntegerToBinary(x << 31));
		System.out.println("====================================>");

		//这个足够看出来3种位移方式的区别了
		//至于?的运算符,+ ^ |三种都行
		//就是个孔雀开屏而已
		for (int shift = 1; shift < Integer.SIZE; shift++)
        {
			System.out.print(getIntegerToBinary(-1 << shift));
			System.out.print(" ? " + getIntegerToBinary(-1 >>> Integer.SIZE - shift));
			System.out.println(" = " +getIntegerToBinary(-1 >> shift));
	        
        }
		System.out.println("====================================>");
		//上边的另外一种实现方式
		int a = -1;
		for (int i =1;i<32; i++)
		{        
            a=a<<1;
            System.out.println(getIntegerToBinary(a)+" ^ "
                                   +getIntegerToBinary(~a)+" = "
                                   +getIntegerToBinary(a+~a));
		}        
		System.out.println("====================================>");

	}
	
	public static final String DEFAULT_INT_ZERO = "00000000000000000000000000000000";
	public static final String getIntegerToBinary(int value)
	{
		String binary = Integer.toBinaryString(value);
		int length = Integer.SIZE - binary.length();
		return DEFAULT_INT_ZERO.substring(0, length) + binary;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值