我尝试转换字节数组以使用其位表示形式。
输入:
byte[] values = new byte[]{21, 117, 41, -1};
我想从字节数组中创建一个BitSet对象,但我将其拆分以调查问题,并尝试从数组的每个元素中创建多个BitSet对象。
BitSet对象是通过以下方式创建的:
BitSet bitSetTwentyOne = BitSet.valueOf(new byte[]{21});
BitSet bitSetOneHundredSevenTeen = BitSet.valueOf(new byte[{117});
BitSet bitSetFourtyOne = BitSet.valueOf(new byte[]{41});
BitSet bitSetMinusOne = BitSet.valueOf(new byte[]{-1});
使用以下方法将位打印出来:
private String getBits(BitSet bitSet) {
StringBuilder bitsBuilder = new StringBuilder();
for (int i = 0; i < bitSet.length(); i++) {
bitsBuilder.append(bitSet.get(i) == true ? 1 : 0);
}
return bitsBuilder.toString();
}
输出:
bitSetTwentyOne: 10101 but expected -> 00010101 (BitSet::length = 5)
bitSetOneHundredSevenTeen: 1010111 but expected -> 01110101 (BitSet::length = 7)
bitSetFourtyOne: 100101 but expected -> 00101001 (BitSet::length = 6)
bitSetMinusOne: 11111111 but it is as expected at least (BitSet::length = 8)
我希望所有值都为8位宽度,即使需要用零填充也是如此。我不明白为什么在转换 117 和 41 时,它给出错误的二进制值。
答案 0 :(得分:3)
length()
使用最高位1传递逻辑长度。size()
会给出8。cardinality()
将给出比特1的数量。所以您应该使用size()
。
然后这些位采用 little endian 格式,您通过首先输出0来反转它。
private String getBits(BitSet bitSet) {
StringBuilder bitsBuilder = new StringBuilder();
for (int i = 0; i < bitSet.size(); ++i) {
bitsBuilder.insert(0, bitSet.get(i) ? '1' : '0');
}
return bitsBuilder.toString();
}
答案 1 :(得分:2)
看来您正在向后打印位。请注意,您的输出(所需的前导零除外)如何是预期输入的镜像。
使用您的代码,传入4
,100
,我得到001
。看来0
位是最低有效位,而不是最高有效位。若要更正此问题,请向后遍历索引。 -1
和41
除前导零外都是正确的原因是它们的位集表示是回文。
要在前导零之前添加,请从length()
中减去8
并打印许多零。 length()
方法仅返回表示该数字所需的位数。您需要自己编写代码;没有用于前导零的BitSet
功能。