每日一面 - 求与数字最接近的 2 的 N 次方

简介: 每日一面 - 求与数字最接近的 2 的 N 次方

对于 2 的 N 次方取余,相当于对 2 的 N 次方减一取与运算,这对于高并发分片计算的时候,很有用。为了对用户友好,我们让用户设置分片数量的时候可能不限制必须是 2 的 N 次方,但是内部我们设置分片的时候,将其设置为最近用户输入数字的 2 的 N 次方的值即可。那么如何计算呢?

抽象为比较直观的理解就是,找一个数字最左边的 1 的左边一个 1 (大于 N 的最小的 2 的 N 次方),或者是最左边的1(小于N的最大的2的N次方),前提是这个数字本身不是2的n次方。


image.png


那么,如何找呢?一种思路是,将这个数字最高位 1 之后的所有位都填上 1,最后加一,就是大于N的最小的 2 的 N 次方。右移一位,就是小于N的最大的 2 的N次方。

如何填补呢?可以考虑按位或计算,我们知道除了 0 或 0=0 以外,其他的都是 1. 我们现在有了最左面的 1,右移一位,与原来按位或,就至少有了两位是 1,再右移两位并按位或,则至少有四位为 1。。。以此类推:


微信图片_20220624204948.jpg


用代码表示是:

n |= n >>> 1; 
n |= n >>> 2; 
n |= n >>> 4; 
n |= n >>> 8; 
n |= n >>> 16;
n += 1;  //大于N的最小的2的N次方
n = n >>> 1; //小于N的最大的2的N次方

如果有兴趣,可以看一下 Java 的 ForkJoinPool 类的构造器,其中的 WorkQueue 大小,就是通过这样的转换得来的。

相关文章
|
10月前
|
Python
如果一个n位正整数等于其各位数字的n次方之和
如果一个n位正整数等于其各位数字的n次方之和
|
算法 测试技术 C#
C++数位算法:数字1的个数
C++数位算法:数字1的个数
|
7月前
|
存储 算法 程序员
极限挑战:40亿个非负整数中找到没有出现的数(bit数组)
大家好!我是小米,一名热衷于技术分享的29岁程序员。今天探讨的问题是在40亿个非负整数中找到未出现的数字。直接使用哈希表因内存限制而不可行。本文提出了一种解决方案——利用bit数组。通过标记出现过的数字,最终找出未被标记的位置所对应的数字即为答案。对于更严格的内存限制(如10MB),文章还介绍了分块处理的方法,先统计每个区间的数字数量,找到计数不足的区间后再精确处理。这种算法不仅展示了巧妙利用有限资源的能力,也为实际工程问题提供了解决思路。希望各位读者能从中受益,享受编程带来的乐趣!
105 15
|
10月前
|
机器学习/深度学习
判断一个数字是否是2的N次方
判断一个数字是否是2的N次方
90 0
|
10月前
|
算法 测试技术 C#
【位运算 拆位法 二分】3007. 价值和小于等于 K 的最大数字
【位运算 拆位法 二分】3007. 价值和小于等于 K 的最大数字
|
10月前
|
算法 测试技术 C++
【位运算】【二分查找】【C++算法】100160价值和小于等于 K 的最大数字
【位运算】【二分查找】【C++算法】100160价值和小于等于 K 的最大数字
|
10月前
|
算法 测试技术 C++
【数位dp】【C++算法】600. 不含连续1的非负整数
【数位dp】【C++算法】600. 不含连续1的非负整数
|
10月前
判断一个数字是否可以表示成三的幂的和(难度:中等)
判断一个数字是否可以表示成三的幂的和(难度:中等)
357. 计算各个位数不同的数字个数
357. 计算各个位数不同的数字个数
357. 计算各个位数不同的数字个数