user466534
user466534

Reputation:

Reverse bits in number

For example, I have the binary number 1011 which is equal to decimal 11. I want the reverse bit's location such that it become 1101, which is decimal 13. Here is code:

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);
    }
}

But when I enter x 11 then it prints 26. What is the mistake?

Upvotes: 20

Views: 46349

Answers (13)

Mukesh Singh Rathaur
Mukesh Singh Rathaur

Reputation: 13135

//    i/p=3 
//    o/p=3221225472
// Clearly observe the 1L while doing the left shift, if ignored it will fail to return the expected output dur to mismatch in bit size.

    public static long reverse(long n) {
        long rev = 0;
        for(int i = 31; i >=0; i--){
            if((n & 1<<i) != 0){
                rev = rev | 1L<<(31-i);
            }
        }
        return rev;
    }

Upvotes: 0

Tom
Tom

Reputation: 86

Note for beginners: I use hexadecimal (0-9 and A-F) because one hexadecimal digit maps to 4 binary bits perfectly. Instead of writing 1010, I use A (10 decimal). You can tell Java to use hexadecimal (literals) by starting with 0x as in 0x0A.

As stated before, 1 should output 8 (0001 to 1000). So instead of while(x!=0), the code needs to shift the first bit as far as the length of the bits needed in this example it is 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

Or full 8 bit example:

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();
}

Output:

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

Upvotes: 2

My new java code reverse bits in an integer using java with powerful bit manipulation. It is working with positive, negative and zero values. Hope it helps.

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;
    }

You can represent bits in integer with my other bit manipulation code in java what print zeroes on the left: https://stackoverflow.com/a/39056535/6738542

Because Integer.toBinaryString() will hide the zeroes on the left.

Metal |,,|

Upvotes: 0

Rahul
Rahul

Reputation: 21

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

Upvotes: 1

Lester
Lester

Reputation: 21

The program do not work for input like 1, 2

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

input 1 output 1, should be 8 right? input 2 output 1, should be 4.

Upvotes: 2

Murali Mohan
Murali Mohan

Reputation: 759

It is safe to use the unsigned right shift operator (>>>) in the while loop to obviate the danger of running into an infinite loop for -ve numbers.

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

Upvotes: 0

user2053554
user2053554

Reputation: 41

  1. Use >>>= instead of >>=
  2. If you want to change method signature to public static byte reverse(byte in) this will not work on negative values because there is implicit cast to int.

Upvotes: 4

Andreas Dolk
Andreas Dolk

Reputation: 114817

The result is twice as much as expected so the last left shift operation (one left shift doubles the value) is too much.

Upvotes: 0

Praetorian
Praetorian

Reputation: 109289

You're left shifting b one time more than required. Add b >>= 1 after your while loop.

Upvotes: 1

Tansir1
Tansir1

Reputation: 1819

Slightly offtopic. There's also the option of the built-in bit reversing features of Java.

See http://java.sun.com/javase/6/docs/api/java/lang/Integer.html#reverse(int)

EDIT: This assumes you're using Java 1.5 or newer.

Upvotes: 16

maranas
maranas

Reputation: 1416

you shifted b once too many. try shifting b to the left before doing the |=:

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

         }
   System.out.println(b);

Upvotes: 1

Peter G.
Peter G.

Reputation: 15144

b is shifted left once too often. I expect input 1 to result in output 2. Move the Shift two lines up.

Upvotes: 1

Thomas
Thomas

Reputation: 182063

You are shifting b one time too many. Do the shift first (so that the first time, when b == 0, it has no effect):

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

Upvotes: 30

Related Questions