“Bitwising” – Bitwise Operations in Java

I have a bad memory concerning particular details of programming languages which I don’t use very often, and bitwise operations are a good example of such details. Therefore, I decided to develop a Java program that serves the purpose of recapping the concepts that I’ve learned in school a few years ago.

In the following table one may find a short overview of the operations that are covered in the simple program below.

Operator Name Description Examples
~ not Unary operation that performs logical negation on each bit. After negation, bits that have the value 0 will have value 1 and the ones having value 1 will have value 0. ~4 = -5

~ 00000100

=11111011

& and Performs the logical AND operation on pairs of corresponding bits of the different numbers. The result is 1 if the pair of bits under comparison is 1, and 0 otherwise. 7&1 = 1

00000111 &

00000001 =

00000001

| or Performs the logical inclusive OR operation on pairs of corresponding bits of the different numbers. The result is 1 if at least one of the bits of the pair under comparison is 1, and 0 otherwise. 7 | 1 = 7

00000111 |

00000001 =

00000111

^ xor Performs the exclusive OR operation on pairs of corresponding bits of the different numbers. The result is 1 if the pair of bits under comparison is different, and 0 otherwise. 7^1 = 6

00000111 ^

00000001 =

00000110

<< signed left shift Shifts the bit pattern on the left operand n positions to the left. Value n is specified by the right hand side operand. Bits with value of 0 are shifted into the low order positions. Equivalent to multiply by 2, the result of the operation value << n is the same as calculating the expression value * (2^n).  7 << 2 = 28

00000111 << 2

=00011100

>> signed right shift Shifts the bit pattern on the left operand n positions to the right. Value n is specified by the right hand side operand. Bits with value of 0 or 1 are shifted into the high order positions in order to preserve the sign. Equivalent to divide by 2. the result of the operation value >> n is the same as calculating the expression value / (2^n). 7 >> 2 = 1

00000111 >> 2

=00000001

>>> unsigned right shift This operation is identical to the signed right shift operation with the exception that it inserts 0 in the high order bits, therefore the sign value may change.

If the left hand side operand is positive, the result will be the same as the signed right shift operation.

If the left hand side operand is negative, the result is equivalent to right shift n positions, specified by the value on the right hand side operand, of the bit pattern on the left-hand side operand. As the high order bits will be zero filled, the sign may change.

 

7 >>> 2 = 1

00000111 >>> 2

=00000001

 

Note: An example with negative numbers is provided in the source code.

Bitwise Operators Demo

The program is rather simple. It generates two random numbers between 0 and 5000, and then applies the bitwise operations to the numbers generated.

A special method for printing the binary representation of the number was used
because AFAIK the method “Integer.toBinaryString(…)” does not return the most
significant part of the binary numbers and for my purpose I wanted to have this
part represented in the output.

Output

The generated output is a set of messages containing the results of the performed
operations, and looks like this:

* Operator: AND &
 Binary representation: 00001000 10101101 - Decimal Representation: 2221
 Binary representation: 00000101 00001000 - Decimal Representation: 1288
 Binary representation: 00000000 00001000 - Decimal Representation: 8


Source Code


package examples.operators.bitwise;

import java.util.Random;

public class BitwiseOperators
{
public static void main(String[] args)
{
System.out.println("*************************");
System.out.println("* Bitwise Operators Demo");
System.out.println("*************************");

// generate a random Integer between 0 and 5000
Random randomNumber = new Random();
int firstValueGenerated = randomNumber.nextInt(5000);
int secondValueGenerated = randomNumber.nextInt(5000);

System.out.println("First Generated Integer: " + firstValueGenerated);
System.out.println("Second Generated Integer: " + secondValueGenerated);

// print generated numbers in binary
IntToBinary(firstValueGenerated);
IntToBinary(secondValueGenerated);

System.out.println(" ");
System.out.println("*************************");
System.out.println("* Operations & Results   ");
System.out.println("*************************");

System.out.println(" ");
System.out.println("* Operator: NOT (Complement) ~ ");
IntToBinary(firstValueGenerated);
IntToBinary(~firstValueGenerated);

System.out.println(" ");
System.out.println("* Operator: Negative -");
IntToBinary(firstValueGenerated);
IntToBinary(-firstValueGenerated);

System.out.println(" ");
System.out.println("* Operator: AND &");

IntToBinary(firstValueGenerated);
IntToBinary(secondValueGenerated);
IntToBinary(firstValueGenerated & secondValueGenerated);

System.out.println(" ");
System.out.println("* Operator: OR |");

IntToBinary(firstValueGenerated);
IntToBinary(secondValueGenerated);
IntToBinary(firstValueGenerated | secondValueGenerated);

System.out.println(" ");
System.out.println("* Operator: XOR ^");

// 1 if the two bits are different, and 0 if they are the same.
IntToBinary(firstValueGenerated);
IntToBinary(secondValueGenerated);
IntToBinary(firstValueGenerated ^ secondValueGenerated);

System.out.println(" ");
System.out.println("* Operator: Signed left shift << (i.e. value << 2)");

IntToBinary(firstValueGenerated);
IntToBinary(firstValueGenerated << 2);

System.out.println(" ");
System.out.println("* Operator: Signed right shift >> (i.e. value >> 2)");

IntToBinary(firstValueGenerated);
IntToBinary(firstValueGenerated >> 2);

System.out.println(" ");
System.out.println("* Operator: Unsigned right shift >>> (i.e. value >>> 2)");

IntToBinary(firstValueGenerated);
IntToBinary(firstValueGenerated >>> 2);

System.out.println(" ");
System.out.println("* Operator: Unsigned right shift >> (Negative values: -16 >> 2)");
IntToBinary(-16);
IntToBinary(-16 >> 2);

System.out.println(" ");
System.out.println("* Operator: Unsigned right shift >>> (Negative values: -16 >>> 2)");
IntToBinary(-16);
IntToBinary(-16 >>> 2);

System.out.println(" ");
System.out.println("* Operator: Unsigned right shift >>> (Negative values: -1 >>> 24)");
IntToBinary(-1);
IntToBinary(-1 >>> 24);
}

private static void IntToBinary(int number)
{
String binaryNumber = new String();

// used for formatting the string
int counter = 0;

// check each bit of the number
for (int i = 31; i >= 0; i--)
{
/*
* Here we are interested in the result of the AND operation:
*
* If the AND operation returns a binary number different than 0
* that means that there was a match between the "mask" that we
* are applying and the number, therefore the string value will be 1
*
* If the AND operation returns 0 that means that the "mask" didn't
* match any bit of the number, therefore the number will be 0
*
*/

if( ((1 << i) & number) != 0)
{
binaryNumber += "1";
}
else
{
binaryNumber += "0";
}

// separate each 8 bits with a space except the last octet
counter++;
if(counter % 8 == 0 && i != 0)
{
binaryNumber += " ";
}
}

System.out.println("Binary representation: " + binaryNumber +
" - Decimal Representation: " + number);
}
}

Feel free to comment out and to suggest new topics or examples or if you think that something should be more detailed or explained.

 

Advertisements
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: