如何在Java中对long数组执行n位左右移位操作
Java中对long数组执行n位位移操作的实现
当需要把long数组当作连续的超长二进制序列执行位移操作时,不能直接对单个元素用位移运算符,必须处理跨元素的位传递。以下是无符号右移(>>> n)和左移(<< n)的具体实现逻辑和代码:
一、无符号右移(>>> n)
无符号右移会将整个超长序列的所有位向右移动n位,左侧补0。实现逻辑:
- 拆分位移为整元素移动次数和剩余位偏移:
fullShifts = n / 64(每64位对应一个long元素),shift = n % 64 - 若整元素移动次数大于等于数组长度,结果数组全为0
- 从数组末尾(最低位块)往前遍历,每个元素的新值由前一个块的低位和当前块的高位拼接而成;超出范围的元素直接设为0
代码实现
import java.util.Arrays; public static void unsignedRightShift(long[] array, int n) { int length = array.length; int fullShifts = n / 64; int shift = n % 64; if (fullShifts >= length) { Arrays.fill(array, 0); return; } // 从末尾往前处理元素 for (int i = length - 1; i >= 0; i--) { if (i >= fullShifts) { long val = array[i - fullShifts] >>> shift; // 拼接前一个块的高位部分(非首个移动元素时) if (i > fullShifts) { val |= array[i - fullShifts - 1] << (64 - shift); } array[i] = val; } else { array[i] = 0; } } }
二、左移(<< n)
左移会将整个超长序列的所有位向左移动n位,右侧补0。实现逻辑:
- 同样拆分位移为
fullShifts = n / 64和shift = n % 64 - 若整元素移动次数大于等于数组长度,结果数组全为0
- 从数组开头(最高位块)往后遍历,每个元素的新值由当前块的低位和后一个块的高位拼接而成;超出范围的元素直接设为0
代码实现
import java.util.Arrays; public static void leftShift(long[] array, int n) { int length = array.length; int fullShifts = n / 64; int shift = n % 64; if (fullShifts >= length) { Arrays.fill(array, 0); return; } // 从开头往后处理元素 for (int i = 0; i < length; i++) { if (i <= length - 1 - fullShifts) { long val = array[i] << shift; // 拼接后一个块的低位部分(非最后一个移动元素时) if (i < length - 1 - fullShifts) { val |= array[i + 1] >>> (64 - shift); } array[i] = val; } else { array[i] = 0; } } }
三、测试示例
用你提供的示例数组测试位移效果:
public class LongArrayShiftTest { // 上述unsignedRightShift和leftShift方法需放在此处 public static void main(String[] args) { long[] values = new long[]{ 0b1011010011111111001100111000000100110011101101110010001011100001L, 0b1011010011111111001100111000000100110011101101110010001011100001L }; // 测试无符号右移3位 long[] rightShiftCopy = Arrays.copyOf(values, values.length); unsignedRightShift(rightShiftCopy, 3); System.out.println("无符号右移3位结果:"); for (long num : rightShiftCopy) { System.out.println(Long.toBinaryString(num)); } // 测试左移5位 long[] leftShiftCopy = Arrays.copyOf(values, values.length); leftShift(leftShiftCopy, 5); System.out.println("\n左移5位结果:"); for (long num : leftShiftCopy) { System.out.println(Long.toBinaryString(num)); } } }
说明
- 默认数组位序:
values[0]为超长序列的最高64位,values[1]为次高64位,以此类推;若你的数组位序相反(values[0]是最低位块),只需调整遍历方向和索引计算即可
内容的提问来源于stack exchange,提问作者linker
相关产品推荐
相关产品推荐

