我怎样才能得到位的位置

use*_*349 5 java algorithm binary bit-manipulation

我有一个十进制数,我需要转换为二进制,然后在二进制表示中找到一个的位置.

输入为5,二进制为101,输出应为

1
3
Run Code Online (Sandbox Code Playgroud)

下面是我的代码,它只提供输出,2而不是我想提供一个二进制表示的位置.如何从1开始获取设置位的位置?

public static void main(String args[]) throws Exception {
    System.out.println(countBits(5));
}

private static int countBits(int number) {
    boolean flag = false;

    if (number < 0) {
        flag = true;
        number = ~number;
    }
    int result = 0;
    while (number != 0) {
        result += number & 1;
        number = number >> 1;
    }
    return flag ? (32 - result) : result;
}
Run Code Online (Sandbox Code Playgroud)

ajb*_*ajb 9

您想要countBits返回结果而不是放入System.out.println方法内部通常是最好的方法.如果你想要它返回一个位位置列表,那么模拟将是你的方法返回一个数组或某种List,如:

private static List<Integer> bitPositions(int number) {
Run Code Online (Sandbox Code Playgroud)

正如我在评论中提到的,如果您使用>>>并删除特殊代码来检查否定,您将使自己的生活更轻松.这样做,并调整你已有的代码,给你一些类似的东西

private static List<Integer> bitPositions(int number) {
    List<Integer> positions = new ArrayList<>();
    int position = 1;
    while (number != 0) {
        if (number & 1 != 0) {
            positions.add(position);
        }
        position++;
        number = number >>> 1;
    }
    return positions;
}
Run Code Online (Sandbox Code Playgroud)

现在呼叫者可以做他们想要打印的位置.如果你使用System.out.println它,输出将是[1, 3].如果您希望每个输出在单独的行上:

for (Integer position : bitPositions(5)) {
     System.out.println(position);
}
Run Code Online (Sandbox Code Playgroud)

在任何情况下,关于如何打印位置(或者你想用它们做什么)的决定都与计算位置的逻辑分开,因为该方法返回整个列表并且没有自己的位置println.

(顺便说一下,正如Alex所说,最常见的是将低位比特视为"第0位"而不是"第1位",尽管我已经看到将低位称为"第31位"的硬件手册将其命名为"位0"的优点是位置N中的1位表示值2 N,这使得事情变得简单.我的代码示例将其称为"位1",如您所要求的那样在您的问题中;但如果您想将其更改为0,只需更改初始值position.)


Ale*_*lex 5

二进制表示形式:您的数字,就像现代(非量子)计算机上的任何东西一样,已经是内存中的二进制表示形式,作为给定大小的位序列。

位运算 您可以使用位移位、位掩码、“AND”、“OR”、“NOT”和“XOR”按位运算来操作它们并获取有关它们的各个位级别的信息。

你的例子

对于您的示例数字 5 (101),您提到您的预期输出将为1, 3。这有点奇怪,因为一般来说,从 0 开始计数,例如 5 作为一个byte(8 位数字):

     76543210  <-- bit index
5    00000101
Run Code Online (Sandbox Code Playgroud)

所以我希望输出为02因为这些位索引处的位已设置 ( 1)。

您的示例实现显示了该函数的代码

private static int countBits(int number)
Run Code Online (Sandbox Code Playgroud)

它的名称和签名暗示任何实现的以下行为:

  • 它接受一个整数值number并返回一个输出值。
  • 它的目的是计算输入中设置了多少位number

即它与您所描述的预期功能完全不匹配。

一个办法

>>您可以使用“位移位”( ) 和AND( ) 运算的组合来解决您的问题&

int index = 0; // start at bit index 0

while (inputNumber != 0) { // If the number is 0, no bits are set

    // check if the bit at the current index 0 is set
    if ((inputNumber & 1) == 1)         
        System.out.println(index);  // it is, print its bit index.

    // advance to the next bit position to check
    inputNumber = inputNumber >> 1; // shift all bits one position to the right
    index = index + 1;              // so we are now looking at the next index.
}
Run Code Online (Sandbox Code Playgroud)

如果我们对示例输入数字“5”运行此命令,我们将看到以下内容:

iteration   input  76543210     index    result
1           5      00000101     0        1 => bit set.
2           2      00000010     1        0 => bit not set.
3           1      00000001     2        1 => bit set.
4           0      00000000     3        Stop, because inputNumber is 0    
Run Code Online (Sandbox Code Playgroud)