Tuesday, July 27, 2021

Bitwise and BitShift Operators in Java - AND, OR, XOR, Signed Left and Right shift Operator Examples

Bitwise and Bit Shift Operators in Java are a powerful set of operators that allows you to manipulate bits on integral types like int, long, short, bytes, and boolean data types in Java. Bitwise and Bit shift operator is among the fastest operator in Java but still, many Java programmers don't familiar with bitwise and bitshift operations, especially those who don't come from C programming backgrounds. If you have already learned C or C++ before starting with Java then understanding bitwise and bitshift operators are quite easy in Java, because it's similar to the bitwise operation in C.

Some of the tricky programming interview questions e.g. checking if a number is power of two or swapping two numbers without temporary variable or, can be easily solved using bitwise operators. 

This Java programming tutorial is a quick recap of different bitwise operator available in Java and how to use them. This tutorial also discusses bit shift operators, both signed and unsigned for example.

1. Bit and Byte Basics

Before exploring bitwise and bit shift operator in Java, its prerequisite that you must be familiar with binary format, bits, bytes and bit wise operations like AND, OR, XOR, NOT etc. Knowledge of binary arithmetic is also important to understand code written using bitwise operators in Java programming language.

1) Binary format has just two bit,  0 and 1 and that's why is called binary.
2) In binary arithmetic :
0 + 0 =  0
0 + 1 =  1
1 + 1 = 10

3) Negation bitwise operation will change 0 to 1 and 1 to 0 and it’s denoted by ~.
4) OR bitwise operation will return 1 if any of operand is 1 and zero only if both operands are zeros.
5) AND bitwise operation will return 1 only if both operands are 1, otherwise zero.
6) XOR bitwise operation will return 1 if both operands are different e.g. one of them is 1 and other is zero and returns zero if both operands are same e.g. 1,1 or 0,0

7) Integral types in Java (int, long, short and byte) are signed numbers in Java where most significant bit (MSB) represent sign of number. 1 will denote a negative number and 0 as MSB will denote a positive numbers

8) Negative numbers in Java are represented as 2's complement of number. 2's complement of a number is 1's complement + 1 and 1's complement means all zero will turn to 1 and all 1 turned to zero in a binary number e.g. 1's complement of 10 would be 01. and 2's complement of 10 would be 10+1 = 11 (all in binary).





2. Bitwise operators in Java

Java provides several bitwise operator e.g. ~ for the complement, & for AND bitwise operation, | for OR bitwise operation and ^ for bitwise XOR operation. All of these operator implements their respective operation and operates on bit level. By the way bitwise AND and OP operators are entirely different than logical AND && and logical OR operators ||, which operates on boolean variables and also implements AND and OR operation. 

The bitwise operator compares each bit of two operands, for example, if you apply bitwise AND operator & on two integers ( which is a 32-bit data type in  Java), bitwise AND  will apply AND operation on each bit of both operands.

Bitwise and BitShift Operators in Java - AND, OR, XOR, Signed Left and Right shift Operator Examples



3. Bitwise Operators Examples in Java

In this section we will see example of each of bitwise operator e.g. bitwise negation or complement operator (~), bitwise AND (&), bitwise OR(|) and bitwise XOR(^) operator in Java.

3.1 Bitwise unary complement operator (~) Example

Bitwise unary complement operator changes bits from 0 to 1, or vice versa and can only be applied on integral types. It’s not applicable on boolean types.For example int variable contains 32 bits; Applying this operator to a value whose bit pattern is 0000 would change its pattern to 11111. Here is an example of bitwise unary complement operator in Java :

int number = 2; //0010
    
//example of bitwise unary complement operator (~)
System.out.println(" value of number before: " + number);
System.out.println(" value of number after negation: " + ~number);

Output:
value of number before: 2
value of number after negation: -3



3.2 Bitwise AND operator (&) Example

Bitwise AND operator works similar to logical AND operator (&&) and returns 1 if both operands are 1. Difference with bitwise AND and logical AND also known as short-circuit AND operator is that, logical AND operator applies only to boolean type. Also bitwise AND operator is denoted by singe & while short circuit AND operator is denoted by &&. If A represent 0010 and B represent 1010 then result of A&B would be 0010. Here is another example of bitwise AND operator in Java

int a = 2; //0010
int b = 4; //0100

//example of bitwise AND operator &
System.out.println("Result of a&b  is " + (a&b));  //should be zero

Output:
Result of a&b  is 0



3.3 Bitwise OR operator (|) Example

Bitwise OR operator is also similar to bitwise AND operator and applies to individual bits. It’s different than short-circuit OR operator, which is denoted by (||) and operates on boolean variable. Bitwise OR operator produce result of OR operation on two bits as shown in below example. Like other bitwise operator in Java, bitwise OR is only applicable to integral types.

int a = 2; //0010
int b = 4; //0100
      
System.out.println(" value of A bitwise OR B in Java : " + (a|b) );

Output:
value of A bitwise OR B in Java : 6


3.4 Bitwise XOR operator (^) Example

Bitwise XOR operator is denoted by ^ and also work on individual bits. There is no short-circuit XOR operator in Java and result of bitwise XOR operator is XOR operation of individual bits. see the truth table of XOR operation for predicting result. in short bitwise XOR operators will return 1 if both bits are different and return 0 if both bits are same. Bitwise XOR operator also offers a nice trick to swap two numbers without using temp variables.  Here is a code example of using bitwise XOR operator in Java:

int a = 2; //0010
int b = 4; //0100
      
System.out.println(" value of a XOR B in Java : " + (a^b) );

Output:
value of a XOR B in Java : 6


4. Bit Shift operator in Java- Example

Apart from bitwise operators, Java also provides bit shift operators, which can be used to shift bit from one position to another on both left and right side in a number. Java provides three bit shift operator signed left shift operator "<<", signed right shift operator ">>" and unsigned right shift operator ">>>"

Left shift operator with sign, shifts bit into left side and fill the empty place with zero, while right shift operator with sign, shifts the bit on right side and fills the empty place with value of sign bit.  

For positive number it fills with zero and for negative numbers it fills with 1. On the other hand ">>>" right shift without sign operator will only shift the bit towards right without preserving sign of number. 

As per syntax of bitshift operator, left hand side of operand is the number whose bit needs to be shift and right hand side of operator is how many bits needs to shift. This will be much clear with following example of signed left shift, signed right shift and right shift without sign operators:

public class BitShiftTest {

    public static void main(String args[]) {
       
     int number = 8; //0000 1000
     System.out.println("Original number : " + number);
   
     //left shifting bytes with 1 position
     number = number<<1; //should be 16 i.e. 0001 0000

     //equivalent of multiplication of 2
     System.out.println("value of number after left shift: " + number);
   
     number = -8;
     //right shifting bytes with sign 1 position
     number = number>>1; //should be 16 i.e. 0001 0000

     //equivalent of division of 2
     System.out.println("value of number after right shift with sign: " + number);
   
     number = -8;
     //right shifting bytes without sign 1 position
     number = number>>>1; //should be 16 i.e. 0001 0000

     //equivalent of division of 2
     System.out.println("value of number after right shift with sign: " + number);
   
    }  
      
}

Output:
Original number : 8
value of number after left shift: 16
value of number after right shift with sign: -4
value of number after right shift with sign: 2147483644


From above example of bit shift operators in Java, you can imply that signed left shift operators are equivalent of multiplying by 2 and signed right shift operator with sign are dividing by two. I won’t suggest to do that in production quality code, because it reduces readability.

5. Important points to remember while using bit shift operators in Java


1. Smaller types like byte, short are promoted to int before applying bit shift operator in Java. This requires explicit casting on lower type of result.

2. If number of shift positions exceeds with number of bits in a variable, then remainder operator is used to calculate effective bit movement. For example int variables contains 32 bit, and if you shift bits to 33 times, then its equivalent of shifting bits 33%32 or just 1 time. e.g. 8 >> 33 is equal to 8 >> 1 and this is true for all bit shift operators.

3. Since bit shift operators can simulate divide by 2 and multiplied by 2 operation they can be used to implement fast multiplication and division but on the cost of readability as its difficult to comprehend code written using bit shift operators in Java.

That's all on bitwise and bit shift operators in Java. We have seen basics and examples of different bitwise e.g. AND, OR and XOR and bitshift operators such as right shift, left shift and right shift without sign. Java is very rich in terms of bit wise operations and not only provides operators to manipulate bits but also bit shift operator which can move bits on both left and right direction. Only caveat of bitwise and bit shift operator is readability but they are the first choice if you intend to do fast operations in Java.


Related Java Programming articles from Javarevisited Blog

15 comments :

Unknown said...

>> 1's complement of 10 would be 01. and 2's complement of 10 would be 10+1 = 11 (all in binary).
----------

Hm, two's compliment of 10 will be 01+1, which is 10. Right?

Javin @ method override error in eclipse java 5 said...

@Sergey Rogov, you are absolutely correct, that a typo. Thanks for pointing that out.

Anonymous said...

"then its equivalent of shifting bits 33%32 or just 1 time. e.g. 8 >> 33 is equal to 8 >> 33"
Don't you mean 8 >> 33 is equal to 8 >> 1

Javin @ Override Error in Eclipse Java 5 said...

@Anonymous, good catch, you are correct, I actually meant 8 >> 1. Thanks

Ram said...

For positive number it fills with zero and for negative numbers it fills with 1.

Please check this one? is it true or reverse is true?

Anonymous said...

I have two different variables defined as byte e.g.
byte a;
byte c;
a = a|c;
I have to do the Or operations between them but unfortunatelly does not give the right one. it responds always different values. I wrote a function but nothing changes. Any idea.

Anonymous said...

The ~ of int 2 should be more like 1111111111111111111111111111101 not 1101 or -3 as you say since ints are 32 bit.

Anonymous said...

You should probably update your comments here. You have right shifts (with and without) sign saying that the answer should be 16. Obviously 1000 right shifted with sign is 1100 which is your -4 (in 2's complement form). I think you just copied the comments over and forgot to change them.

Anonymous said...

The ~ of 2(0010) is 1101 which is -5. Right?

Anonymous said...

The ~ of 2(0010) is 1101 which is -5. Right? - Wrong it is -3.

Anonymous said...

I am commenting here since most of you have confusion with the ~2:
Explanation:
int number = 2 will store 2 as a 32 bit integer value: 00000000000000000000000000000010
When you do ~2, the bits will be inverted i.e 1 will become 0 and vice versa. The inverted number will be 11111111111111111111111111111101
This number is in 2's complement form represent -3.
Since int stores all the numbers in their 2's complement form the result is -3.

Unknown said...

how to multiply by 3 or divide by 3 using bitwise operators ?

Anonymous said...

Meherprasad ... these are binary operators .. i.e. powers of 2. If you want to do general math, then don't use these operators. (I.e. just do /= 3 or *= 3 instead.)

Or ... invent a base-3 based computer, where each bit represents 3 numbers, then I guess << 1 would be a *= 3 for you ;)

Privacy Policy said...

If the 2's complement of 2's complement are same than answer will cosider as 1's

Kiran Bhagwat said...

Adding two numbers using bitwise operator

int add(int a,int b)
{
int sum,carry;
if (b == 0)
return a;
sum = a ^ b; // add without carrying
carry = (a & b) << 1; // carry, but don’t add
return add(sum,carry); // recurse
}

Post a Comment