删除特定索引处的位

我基本上试图从特定索引处的整数中删除一点。 也就是说,我不想取消/清除这一点; 我实际上想剥离它,以便每个更高的位向下移动,替换其位置的相应位。 在视觉上,可以将其与从数组中删除元素或从字符串中删除字符进行比较。
为清楚起见,举例说明:

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); return out; } 

…除了一些极端情况外,几乎总是有效的:

 10000000000000000000000000000001 (= Integer.MAX_VALUE - 1) ^ index = 31, results in: 10000000000000000000000000000001 1011011 ^ index = 0, results in: 1111111 

换句话说,如果索引是0或31(最小或最高位),我的方法将输出垃圾。
我似乎无法绕过它,这就是我要问的原因:

如何删除32位整数中的任意位?
我特别希望用Java(最小的内存和CPU消耗)来实现最高性能的方法,因为这个操作必须运行至少几百万次。 这就是为什么像“将其转换为字符串,删除字符并将其转换回来”之类的东西是不可能的。

正如评论中所解释的那样,class次计数翻到> = 32,这造成了麻烦。

无论如何,让我们找到一种方法来做到这一点。

首先考虑两个“碎片”,低碎片(在原始位置复制,可能在0 … 31位长之间的任何位置)和高碎片(向下移动一个,也可以在0之间) .. 31位长)。 碎片的总长度始终为31。

低件的面具很明显: ~(-1 << i)

这使得高件的面具显而易见: ~lowmask << 1 。 无论如何,高件都会移动,因此可以进行换档。

现在剩下的就是把碎片和它们放在一起,你会得到的

 static int removeBit(int x, int i) { int mask = ~(-1 << i); return (x & mask) | ((x >>> 1) & ~mask); } 

扔掉双重否定:

 static int removeBit(int x, int i) { int mask = -1 << i; return (x & ~mask) | ((x >>> 1) & mask); } 

只需掩盖所需的位,无需来回移动

 public static int removeBit(int num, int index) { int mask = (1 << index) - 1; return ((num & ((~mask) << 1)) >>> 1) | (num & mask); } 

要么

 public static int removeBit(int num, int index) { int mask = (1 << index) - 1; return ((num >>> 1) & ~mask) | (num & mask); }