16


4

数の逆ビット

たとえば、10進数の11に等しい2進数の1011があります。 リバースビットの位置が1101(10進数の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と印刷されます。 間違いは何ですか?

12 Answer


24


「b」を1回シフトしすぎています。 最初にシフトを実行します(最初に、 `b == 0`の場合、効果はありません):

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


14


少しオフトピック。 Javaの組み込みビット反転機能のオプションもあります。

編集:これは、Java 1.5以降を使用していることを前提としています。


3


  1. `>> =`の代わりに `>>> =`を使用します

  2. メソッドのシグネチャを次のように変更する場合 `public static byte reverse(byte in)`これは、intへの暗黙的なキャストがあるため、負の値では機能しません。


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でなければなりません。


2


初心者向けの注意:1つの16進数が4バイナリビットに完全にマッピングされるため、16進数(0-9およびA-F)を使用します。 1010を記述する代わりに、A(10進数の10)を使用します。 0x0Aのように0xで開始することにより、Javaに16進数(リテラル)を使用するように指示できます。

前述のように、1は8(0001〜1000)を出力します。 したがって、while(x!= 0)の代わりに、この例で必要なビットの長さが4である限り、コードは最初のビットをシフトする必要があります。

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


1


bは1回左にシフトしすぎています。 入力1が出力2になることを期待しています。 Shiftを2行上に移動します。


1


bを一度シフトしすぎた。 | =を実行する前にbを左にシフトしてみてください。

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

         }
   System.out.println(b);


1


必要以上に「b」を1回シフトしたままにします。 whileループの後に「b >> = 1」を追加します。


1


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


0


結果は予想の2倍なので、最後の左シフト操作(左シフト1回で値が2倍になります)は多すぎます。