我基本上想在特定的索引处从整数中删除一位。也就是说,我不想取消/清除该位;我实际上想要剥离它,以便每个更高位都向下移动,替换其位置上的相应位。从视觉上来看,这可以与从数组中删除元素或从字符串中删除字符进行比较。
为了更清楚地说明,以下是一些示例:
换句话说,如果索引为0或31(最低位或最高位),我的方法将输出垃圾值。
我似乎无法理解它,这就是为什么我要问:如何从32位整数中删除任意位?
我特别寻找在Java中执行此操作的最有效方式(内存和CPU消耗最小),因为此操作必须运行至少数百万次。这就是为什么像“将其转换为字符串,删除字符并转换回来”之类的方法不可行的原因。
为了更清楚地说明,以下是一些示例:
1011011 (original number)
^ index = 2
0101111 (result)
10000000000000000000000000000001
^ index = 31
00000000000000000000000000000001
1111111111111111111111111111110
^ index = 0
0111111111111111111111111111111
我充满信心地开始移动一些位,然后想出了下面的Java方法...
public static int removeBit(int num, int i) {
int out = (num >>> (i + 1)) << i;
out |= (num << (32 - i)) >>> (32 - i);
return out;
}
...这几乎总是有效的,除了一些极端情况:
10000000000000000000000000000001 (= Integer.MAX_VALUE - 1)
^ index = 31, results in:
10000000000000000000000000000001
1011011
^ index = 0, results in:
1111111
换句话说,如果索引为0或31(最低位或最高位),我的方法将输出垃圾值。
我似乎无法理解它,这就是为什么我要问:如何从32位整数中删除任意位?
我特别寻找在Java中执行此操作的最有效方式(内存和CPU消耗最小),因为此操作必须运行至少数百万次。这就是为什么像“将其转换为字符串,删除字符并转换回来”之类的方法不可行的原因。
num >>> (i + 1)
。向左移动32位与不移动相同(右操作数事先得到AND掩码处理)。 - Marko Topolnikif
语句,但我认为在性能方面可能有更简单的选择。 - MCLif
语句很便宜,我不会太早开始担心它。仅仅使用位操作方法就可以保证出色的性能(几个纳秒)。首先让它工作,然后进行分析,如果必要再进行优化(这种情况非常少见)。 - Marko Topolnik(32 - i)
——这是低端错误的源头。再次超出了31。 - Marko Topolnik