对位运算的应用的验证

上午看到了一篇关于位运算技巧的分享博客,其中有一个例子是关于用位运算求不大于某个数的2的最大幂数,看到他的例子就自己上手验证了一下,虽然不知道博主的思路来源,但验证结果却让人大跌眼镜

1.原文中给出的普通while循环方法:

public static void main(String[] args) {
    // 不讨论负数情况
    int N = Integer.MAX_VALUE - 123456789;
    System.out.println(fixCompute(N));
}
    
public static int compute(int num) {
	if (num == 0) {
		return 0;
	}
    int sum = 1;
    while (true) {
        if (sum * 2 > num) {
            return sum;
        }
        sum *= 2;
        System.out.println(sum);
    }
}

如果你在idea.properties中配置了idea.cycle.buffer.size=disabled,你会得到如下的控制台输出信息
在这里插入图片描述
不仅没有正常输出,而且代码执行会陷入死循环,问题就处在当int类型数据的从左到右数第31位如果为1且小于给定的整数,那么再乘以2就会导致整型溢出变为负数

修改之后的compute方法:

public static int compute(int num){
    long sum = 1;
    while(true){
    	if(sum * 2 > num){
        	return (int)sum;
   		 }
        sum *= 2;
    }
}

2.原文中给出的位运算方法:

public static void main(String[] args) {
        int N = Integer.MAX_VALUE - 123456789;
        System.out.println("给定的整数N = " + N);
        System.out.println("计算出2的幂 = " + bitCompute(N));
    }

    public static int bitCompute(int num) {
        num |= num >> 1;
        num |= num >> 2;
        num |= num >> 4;
        num |= num >> 8;
        return (num + 1) >> 1;
    }

运行之后你会得到一下输出:
在这里插入图片描述
这个结果真的有点小。。。

我怀疑博主写法的起因是因为我认为对于int整型数据,只左移15位是不能保证计算结果恰好是2的次方,我直接的想法就是对于二进制数如果从左到右数第31位为1,其余为0,那么得出的结果就是一个高16位全是1低15位全是0的数据,而正确的结果它本身,这显然不正确,这也说明了上面的错误不能简单通过使用无符号左移来解决

修改之后的bitCompute方法:

public static int bitCompute(int num) {
    num |= num >> 1;
    num |= num >> 2;
    num |= num >> 4;
    num |= num >> 8;
    num |= num >> 16;
    return (num + 1) >>> 1;
}

左移16位确保右起第一个1之后的所有位都被置位1,加1无符号左移1位确保原来的数据除右起第一个1之后的所有1都被置0,就得到了不大于给定整数的2的最大幂数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值