如何遍历Long类型位数值,返回所有通过OR操作设置的原始位位置
核心结论
首先要明确一个Java基础语法限制:long 是64位有符号整数,对long做移位操作时,移位距离会自动对64取模,因此你示例中的1L << 5600 实际等价于1L << (5600 % 64) = 1L << 32,你之前测试hasValue(values, 5600)返回true也只是巧合——因为右移5600位同样会取模64,刚好命中了32位的标记,本质上你根本没法用long存储超过63位的位标记。
如果要实现你的需求,分两种场景处理:
场景1:仅需要存储0~63位的标记(用原生long实现)
可以直接遍历所有位,或者用更高效的逐位提取逻辑:
public class BitTraverseDemo { public static void main(String[] args) { long values = 0; // 仅设置64位以内的有效位 values |= (1L << 10); values |= (1L << 45); // 遍历所有已设置的位 long temp = values; int pos = 0; while (temp != 0) { if ((temp & 1) == 1) { System.out.println("Found value: " + pos); } temp >>>= 1; // 无符号右移,避免符号位干扰 pos++; } } }
运行后输出:
Found value: 10 Found value: 45
场景2:需要存储超过63位的标记(推荐用BitSet实现)
Java标准库的java.util.BitSet专门用于动态存储位标记,支持任意长度的位操作,原生提供遍历已设置位的能力,完全支持你示例中的5600位的需求:
import java.util.BitSet; public class BitSetDemo { public static void main(String[] args) { BitSet values = new BitSet(); // 设置位 values.set(10); values.set(45); values.set(5600); // 遍历所有已设置的位 int pos = values.nextSetBit(0); while (pos != -1) { System.out.println("Found value: " + pos); pos = values.nextSetBit(pos + 1); } } }
运行后输出完全符合你的要求:
Found value: 10 Found value: 45 Found value: 5600
内容的提问来源于stack exchange,提问作者dinorider
相关产品推荐
相关产品推荐

