数字中的位反转

20
例如,我有二进制数1011,它等于十进制数11。我想要反转位的位置,使其变成1101,即十进制数13。以下是代码:

例如,我有二进制数1011,它等于十进制数11。我想要反转位的位置,使其变成1101,即十进制数13。以下是代码:

import java.util.*;
public class bits {
    public static void main(String[] args) {
        Scanner scnr=new Scanner(System.in);
        System.out.println("enter x:");
        int x=scnr.nextInt();
        int b=0;
        while (x!=0){
            b|=( x &1);
            x>>=1;
            b<<=1;
        }
        System.out.println(b);
    }
}

但是当我输入 x 11 时,它打印出来的是 26。错在哪里了?


3
一个完整的整数可以使用 Integer.reverse(int i) 进行反转 - 但是看起来你想要反转比特数更少的整数,我将其留作注释。 - Andreas Dolk
1
看起来解决方案已经在这里了: https://dev59.com/vnRB5IYBdhLWcg3wAjXR 你忽略了最后需要进行额外的移位。 - AndrewB
13个回答

29
你将 b 左移了一次太多。先进行左移操作(这样第一次时,当 b == 0 时,不会产生影响):
while (x!=0){
  b<<=1;
  b|=( x &1);
  x>>=1;
}

如果我们还想考虑填充怎么办?1011实际上是00001011,所以反转必须是10110000。 - Femn Dharamshi
然后,您可以使用一个for循环来执行固定数量的迭代。 - Thomas
你回复了一个11年前的帖子!天啊! 不过没关系,谢谢你!我保持了计数,然后执行了b<<=(8-count)。 - Femn Dharamshi
1
无法抗拒那个红色的通知计数器;) - Thomas

16

4
  1. 使用 >>>= 代替 >>=
  2. 如果你想要将方法签名更改为 public static byte reverse(byte in),这不会对负值生效,因为存在隐式转换为 int。

2

针对初学者的提示:我使用十六进制(0-9和A-F),因为一个十六进制数字可以完美地映射到4个二进制位。所以,我用A(10进制)代替1010。你可以通过以0x开头来告诉Java使用十六进制(字面量),如0x0A。

如前所述,1应输出8(0001变为1000)。因此,代码需要将第一个位移动到所需位数的长度,本例中为4位,而不是使用while(x!=0)。

for (int i = 0; i < 4; ++i) { // not while (x!=0){
   b<<=1;
   b|=( x &1);
   x>>=1;
}
Hex convert 0-F: 0=0 1=8 2=4 3=C 4=2 5=A 6=6 7=E 8=1 9=9 A=5 B=D C=3 D=B E=7 F=F

或者完整的8位示例:

public static byte reverse(byte x) {
    byte b = 0;
    for (int i = 0; i < 8; ++i) {
        b<<=1;
        b|=( x &1);
        x>>=1;
      }
    return b;
}
public static void main(String args[]) {
    byte[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 
            (byte) 0xAA, (byte) 0xFE, (byte) 0xFF };
    for (byte b : nums) {
        System.out.printf("%02X=%02X ", b, reverse(b));
    }
    System.out.println();
}

输出:

00=00 01=80 02=40 03=C0 04=20 05=A0 06=60 07=E0 08=10
09=90 0A=50 0B=D0 0C=30 0D=B0 0E=70 0F=F0 10=08 11=88 AA=55 FE=7F FF=FF

2
程序不能处理像1、2这样的输入。
int reverseBits(int x)
    {
        int b = 0;
        while (x != 0)
        {
            b <<= 1;
            b |= ( x & 1);
            x >>= 1
        }
        return b;
    }

输入1输出1,应该是8对吗? 输入2输出1,应该是4。


1
while(x!=0){
    b<<=1;
    b|=(x&1);
    x>>=1;
}

1

你将 b 左移了一次过多。在执行 |= 操作之前,尝试将 b 左移一下:

    while (x!=0){
           b<<=1;
           b|=( x &1);
           x>>=1;

         }
   System.out.println(b);

1
问题描述:变量 b 左移了一次太多。我期望输入 1 会得到输出 2。请将“Shift”这行代码上移两行。

1

你将 b 左移了比所需的多一次。在 while 循环后添加 b >>= 1


0

我的新Java代码使用强大的位操作反转整数中的位。它可以处理正数、负数和零值。希望它能有所帮助。

public static int  reverseDigits(int num) throws Exception {
        if (num == 0) {         
            return Integer.MAX_VALUE | Integer.MIN_VALUE;
        }

        int count = Integer.SIZE * 8 - 1;
        int  reversed = num;        
        boolean positive = true;

        if (num < 0) {
            positive = false;
        }

        if (positive) num >>= 1;

        while(num != 0) {

            reversed <<= 1; 
            reversed |= (num & 1);          

            num >>>= 1;
            count--;            
        }

        if (positive) reversed <<= count;
        return reversed;
    }

你可以使用我在Java中的其他位操作代码来表示整数中的位,并打印左侧的零: https://dev59.com/5W435IYBdhLWcg3wtSUV#39056535

因为Integer.toBinaryString()会隐藏左侧的零。

金属 |,,|


如果你使用这行代码:boolean positive = (num < 0) ? false : true;,就会好得多,而且可以忘记下一个if语句。 - Róbert Kovács
“throws Exception” 不重要,我只是用它进行其他测试。 - Róbert Kovács
或者 boolean positive = num>=0; - Florian F

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接