如何向long类型数字插入位?特定位置插位可行性咨询
在long类型数字的二进制中插入指定位的实现方案
没问题,我来帮你搞定这个二进制位插入的需求,先从你的示例入手拆解,再给出通用实现代码。
首先得明确一个关键细节:position参数的索引定义。从你的例子来看:输入数字n=18(二进制10010),调用insert(n,2)后得到42(二进制101010)——相当于在原二进制的从左数第2位之后插入了1(原序列是10 010,插入后变成10 1 010)。不过在位操作的场景里,我们更习惯用「从右往左、从0开始」的索引,所以先把两种场景都覆盖到。
核心实现思路
不管用哪种索引定义,核心逻辑都是一样的:
- 把原数字拆成高位部分和低位部分,中间腾出要插入的位的空间
- 将高位部分左移1位,给新插入的位留出位置
- 在腾出的位置上设置要插入的位(这里是1,要是需要插入可变位可以改成参数)
- 把高位左移部分、插入位、低位部分合并起来
代码实现
1. 按「从右往左、0开始」的索引插入
这是最通用的位操作实现,position参数表示插入后新位所在的索引:
public static long insert(long numb, int position) { // 校验参数:long是64位,索引只能在0-63之间 if (position < 0 || position >= 64) { throw new IllegalArgumentException("Position must be between 0 and 63 inclusive"); } // 提取原数字中低于position的低位部分 long lowerBits = numb & ((1L << position) - 1); // 提取高位部分并左移1位,腾出插入位置 long upperBitsShifted = (numb & (~((1L << position) - 1))) << 1; // 插入1到目标位置,合并所有部分 return upperBitsShifted | (1L << position) | lowerBits; }
测试你的示例:要得到101010,对应的从右索引是3(新插入的1在第3位),调用insert(18, 3)就会返回42,和你的预期一致。
2. 按「从左往右、1开始」的索引插入(匹配你的示例)
如果想直接用你示例里的position=2(从左数第2位之后插入),可以加个辅助方法先转换索引:
// 辅助方法:计算long数字的二进制有效长度 private static int getBinaryLength(long numb) { if (numb == 0) return 1; // 利用Long类的工具方法计算前导零的数量,得到有效长度 return 64 - Long.numberOfLeadingZeros(numb); } // 按从左数的位置插入(position从1开始) public static long insertFromLeft(long numb, int position) { int binaryLength = getBinaryLength(numb); if (position < 1 || position > binaryLength) { throw new IllegalArgumentException("Position must be between 1 and " + binaryLength + " inclusive"); } // 转换为从右往左的索引 int rightPosition = binaryLength - position; return insert(numb, rightPosition); }
现在调用insertFromLeft(18, 2),就会直接返回42,完全匹配你的示例需求。
关键注意点
- 一定要用
1L而不是1:因为1是int类型,左移超过31位会溢出,而1L是long类型,能覆盖64位的操作。 - 参数校验很重要:避免传入超出long范围的索引,导致意外的溢出或错误结果。
内容的提问来源于stack exchange,提问作者RV1DEN
相关产品推荐
相关产品推荐

