有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中的二进制求逆整数

Java中有一种方法可以反转整数reverseBytes()中的位。我想尝试另一种实现,这就是我所拥有的:

public static int reverse(int num) {

        int num_rev = 0;
        for (int i = 0; i < Integer.SIZE; i++) {
            System.out.print((num >> i) & 1);

            if (((num >> i) & 1)!=0) {

                num_rev = num_rev | (int)Math.pow(2, Integer.SIZE-i);
            }

        }
        return num_rev;
}

结果num_rev不正确。有人知道如何“重建”价值吗?也许有更好的方法来执行它

谢谢你的建议


共 (3) 个答案

  1. # 1 楼答案

    您不想使用的原因:

    public static int reverseBytes(int i) {
        return ((i >>> 24)           ) |
               ((i >>   8) &   0xFF00) |
               ((i <<   8) & 0xFF0000) |
               ((i << 24));
    }
    

    编辑: Integer还具有:

    public static int reverse(int i)
    

    Returns the value obtained by reversing the order of the bits in the two's complement binary representation of the specified int value.

  2. # 2 楼答案

    您的代码有两个问题:

    1. 您正在使用int类型转换。你应该做(长)数学。pow(…整数转换的问题是pow(2,n)总是一个正数,因此转换为整数的pow(2,31)将四舍五入为(2^31)-1,因为这是最大的正整数。2^31-1的位字段是0x7ffffff,但在本例中,您需要0x8000000,这正是转换长度的低32位
    2. 您正在执行pow(2,Integer.Size-i)。应该是整数。尺寸-i-1。您基本上希望将位0带到最后一位,将位1带到最后一位,依此类推。但是,最后一位是位31,而不是位32。您的代码正在尝试将位0设置为位整数。SIZE-0==32,所以需要减去1

    以上假设这只是为了好玩。但是,如果确实需要反转位,请不要使用浮点运算。按照其他答案的建议去做

  3. # 3 楼答案

    反转位的正常方法是通过位操作,当然不是通过浮点数学例程

    例如(注意:未经测试)

    int reverse(int x) {
        int y = 0;
        for (int i = 0; i < 32; ++i) {
            y <<= 1;       // make space
            y |= (x & 1);  // copy LSB of X into Y
            x >>>= 1;      // shift X right
        }
        return y;
    }
    

    因为x右移y左移x的原始LSB最终成为y的MSB

    一种很好的(并且相当广为人知的)方法是:

    unsigned int reverse(unsigned int x)
    {
        x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
        x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
        x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
        x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
        return ((x >> 16) | (x << 16));
    }
    

    这实际上是C代码,但由于Java没有unsigned类型来移植到Java,所以您需要做的就是删除unsigned限定符,并使用>>>而不是>>来确保您不会得到任何“符号扩展”

    它的工作原理是:首先每隔一个,然后每隔一个,然后每隔一个字节,然后每隔一个字节,最后是顶部和底部的16位字。这实际上是有效的:)