How big can a computer memory be? Here is a list of memory units from Bit to Coperbyte.

  • 1 Bit = 1 Binary Digit
  • 8 Bits = 1 Byte
  • 1024 Bytes = 1 Kilobyte
  • 1024 Kilobytes = 1 Megabyte
  • 1024 Megabytes = 1 Gigabyte
  • 1024 Gigabytes = 1 Terabyte
  • 1024 Terabytes = 1 Petabyte
  • 1024 Petabytes = 1 Exabyte
  • 1024 Exabytes = 1 Zettabyte
  • 1024 Zettabytes = 1 Yottabyte
  • 1024Yottabytes = 1 Brontobyte
  • 1024 Brontobytes = 1 Geopbyte
  • 1024 Geopbyte = 1 Saganbyte
  • 1024 Saganbyte = 1 Pijabyte
  • 1024 Pijabyte = 1 Alphabyte
  • 1024 Alphabyte = 1 Kryatbyte
  • 1024 Kryatbyte = 1 Amosbyte
  • 1024 Amosbyte = 1 Pectrolbyte
  • 1024 Pectrolbyte = 1 Bolgerbyte
  • 1024 Bolgerbyte = 1 Sambobyte
  • 1024 Sambobyte = 1 Quesabyte
  • 1024 Quesabyte = 1 Kinsabyte
  • 1024 Kinsabyte = 1 Rutherbyte
  • 1024 Rutherbyte = 1 Dubnibyte
  • 1024 Dubnibyte = 1 Seaborgbyte
  • 1024 Seaborgbyte = 1 Bohrbyte
  • 1024 Bohrbyte = 1 Hassiubyte
  • 1024 Hassiubyte = 1 Meitnerbyte
  • 1024 Meitnerbyte = 1 Darmstadbyte
  • 1024 Darmstadbyte = 1 Roentbyte
  • 1024 Roentbyte = 1 Coperbyte

Complete Bit Manipulation and Bitwise Operation Tutorial in Java

Bitwise Operation includes some of the low level operations directly on bit representation. In this tutorial, I will cover the following bit operations and manipulations in Java:

  • AND
  • OR
  • XOR
  • COMPLEMENT
  • LEFT SHIFT
  • RIGHT SHIFT
  • UNSIGNED RIGHT SHIFT
  • SET NTH BIT TO ZERO
  • SET NTH BIT TO ONE

I have used both positive and negative numbers to show you the difference. Here is a summary of how these operations are done:

  • AND is represented by &. (For example¬†a & b)
  • OR¬† is represented by |. (For example a | b)
  • XOR is represented by ^ (For example a ^ b). If two bits are equal, result is 0 otherwise 1.
  • COMPLETEMENT is represented by ~ (flips the bits)
  • LEFT SHIFT is represented by <<
  • RIGHT SHIFT is represented by >> (preserves sign)
  • URSHIFT is represented by >>> (unsigned right shift – does not preserve sign)
  • Setting nth bit to 1: a = a | (1<<n)
  • Setting nth bit to 0: a = a & ~ (1<<n)

Here is the Java Implementation that shows all of the above operations:

package com.icodejava.blog.datastructure;

/**
 * @author Kushal Paudyal
 * www.icodejava.com
 * Created On -  Mar 1, 2014
 * Last Modified On - Mar 1, 2014
 */
public class BitManipulation {

	/**
	 * SUMMARY:
	 * 
	 * AND is represented by &
	 * OR  is represented by |
	 * XOR is represented by ^
	 * COMPLETEMENT is represented by ~ (flips the bits)
	 * LEFT SHIFT is represented by <<
	 * RIGHT SHIFT is represented by >> (preserves sign)
	 * URSHIFT is represented by >>> (unsigned right shift - does not preserve sign)
	 * Setting nth bit to 1: a = a | (1<<n)
	 * Setting nth bit to 0: a = a & ~ (1<<n)
	 */
	
	public static void main(String args[]) {
		int a = 5;
		int b = 6;

		doBitAND(a, b);
		doBitAND(-a, b);

		doBitOR(a, b);
		doBitOR(-a, b);

		doBitXOR(a, b);
		doBitXOR(-a, b);

		doBitComplement(a);
		doBitComplement(-a);

		doBitLeftShift(a, 1); // shift one bit left
		doBitLeftShift(-a, 2); // shift two bits left on -ve number

		doBitRightShift(a, 1); // shift one bit right
		doBitRightShift(-a, 2); // shift two bits right on -ve number

		doBitUnsignedRightShift(a, 1); // shift one bit right, sign not
										// preserved
		doBitUnsignedRightShift(-a, 2); // shift two bits right on -ve number,
										// sign not preserved

		setNthBitToZero(a, 2);
		setNthBitToZero(-a, 1);

		setNthBitToOne(a, 1);
		setNthBitToOne(-a, 2);

	}

	/**
	 * AND is represented by & such as num1 & num2
	 */
	public static int doBitAND(int a, int b) {
		System.out.println("{BITWISE AND OPERATION}\nFirst Number: " + a + "("
				+ Integer.toBinaryString(a) + ") Second Number: " + b + "("
				+ Integer.toBinaryString(b) + ")");

		int result = a & b;

		System.out.println("Result: " + result + "("
				+ Integer.toBinaryString(result) + ")\n");

		return result;

	}

	/**
	 * OR is represented by | such as num1 | num2
	 */
	public static int doBitOR(int a, int b) {
		System.out.println("{BITWISE OR OPERATION}\nFirst Number: " + a + "("
				+ Integer.toBinaryString(a) + ") Second Number: " + b + "("
				+ Integer.toBinaryString(b) + ")");

		int result = a | b;

		System.out.println("Result: " + result + "("
				+ Integer.toBinaryString(result) + ")\n");

		return result;

	}

	/**
	 * OR is represented by | such as num1 ^ num2
	 */
	public static int doBitXOR(int a, int b) {

		System.out.println("{BITWISE XOR OPERATION}\nFirst Number: " + a + "("
				+ Integer.toBinaryString(a) + ") Second Number: " + b + "("
				+ Integer.toBinaryString(b) + ")");

		int result = a ^ b;

		System.out.println("Result: " + result + "("
				+ Integer.toBinaryString(result) + ")\n");

		return result;

	}

	/**
	 * COMPLEMENT is represented by ~ such as ~num
	 */
	public static int doBitComplement(int a) {

		System.out.println("{BITWISE COMPLEMENT OPERATION}\nInput Number: " + a
				+ "(" + Integer.toBinaryString(a) + ")");

		int result = ~a;

		System.out.println("Result: " + result + "("
				+ Integer.toBinaryString(result) + ")\n");

		return result;
	}

	/**
	 * Left shift operation is represented with <<
	 * This operation preserves sign.
	 * Note: one bit left shift is equivalent to number multiplied by two.
	 */
	public static int doBitLeftShift(int a, int numberOfShifts) {

		System.out.println("{BITWISE LEFT SHIFT OPERATION}\nInput Number: " + a
				+ "(" + Integer.toBinaryString(a) + ") Number of bit shifts: "
				+ numberOfShifts);

		int result = a << numberOfShifts;

		System.out.println("Result: " + result + "("
				+ Integer.toBinaryString(result) + ")\n");

		return result;

	}

	/**
	 * Right shift operation is represented with >>
	 * This operation preserves sign.
	 */
	public static int doBitRightShift(int a, int numberOfShifts) {

		System.out.println("{BITWISE RIGHT SHIFT OPERATION}\nInput Number: "
				+ a + "(" + Integer.toBinaryString(a)
				+ ") Number of bit shifts: " + numberOfShifts);

		int result = a >> numberOfShifts;

		System.out.println("Result: " + result + "("
				+ Integer.toBinaryString(result) + ")\n");

		return result;

	}

	/**
	 * Unsigned Right shift operation is represented with >>>
	 * This operation does not preserve sign.
	 */
	public static int doBitUnsignedRightShift(int a, int numberOfShifts) {
		System.out
				.println("{BITWISE UNSIGNED RIGHT SHIFT OPERATION}\nInput Number: "
						+ a
						+ "("
						+ Integer.toBinaryString(a)
						+ ") Number of bit shifts: " + numberOfShifts);

		int result = a >>> numberOfShifts;

		System.out.println("Result: " + result + "("
				+ Integer.toBinaryString(result) + ")\n");

		return result;
	}

	/**
	 * To set nth bit to zero, we follow the following: a = a | (1 << n);
	 * Note: bit count starts with index zero from right.
	 */
	public static int setNthBitToOne(int a, int whichBit) {
		System.out
				.println("{BITWISE SET NTH BIT TO ONE OPERATION}\nInput Number: "
						+ a
						+ "("
						+ Integer.toBinaryString(a)
						+ ") Bit to set one: " + whichBit);

		int result = a = a | (1 << whichBit);

		System.out.println("Result: " + result + "("
				+ Integer.toBinaryString(result) + ")\n");

		return result;
	}

	/**
	 * To set nth bit to one, we follow the following: a & ~(1 << n);
	 * Note: bit count starts with index zero from right.
	 */
	public static int setNthBitToZero(int a, int whichBit) {
		System.out
				.println("{BITWISE SET NTH BIT TO ZERO OPERATION}\nInput Number: "
						+ a
						+ "("
						+ Integer.toBinaryString(a)
						+ ") Bit to set zero: " + whichBit);

		int result = a & ~(1 << whichBit);

		System.out.println("Result: " + result + "("
				+ Integer.toBinaryString(result) + ")\n");

		return result;
	}

}


Result of running the above program:

{BITWISE AND OPERATION}
First Number: 5(101) Second Number: 6(110)
Result: 4(100)

{BITWISE AND OPERATION}
First Number: -5(11111111111111111111111111111011) Second Number: 6(110)
Result: 2(10)

{BITWISE OR OPERATION}
First Number: 5(101) Second Number: 6(110)
Result: 7(111)

{BITWISE OR OPERATION}
First Number: -5(11111111111111111111111111111011) Second Number: 6(110)
Result: -1(11111111111111111111111111111111)

{BITWISE XOR OPERATION}
First Number: 5(101) Second Number: 6(110)
Result: 3(11)

{BITWISE XOR OPERATION}
First Number: -5(11111111111111111111111111111011) Second Number: 6(110)
Result: -3(11111111111111111111111111111101)

{BITWISE COMPLEMENT OPERATION}
Input Number: 5(101)
Result: -6(11111111111111111111111111111010)

{BITWISE COMPLEMENT OPERATION}
Input Number: -5(11111111111111111111111111111011)
Result: 4(100)

{BITWISE LEFT SHIFT OPERATION}
Input Number: 5(101) Number of bit shifts: 1
Result: 10(1010)

{BITWISE LEFT SHIFT OPERATION}
Input Number: -5(11111111111111111111111111111011) Number of bit shifts: 2
Result: -20(11111111111111111111111111101100)

{BITWISE RIGHT SHIFT OPERATION}
Input Number: 5(101) Number of bit shifts: 1
Result: 2(10)

{BITWISE RIGHT SHIFT OPERATION}
Input Number: -5(11111111111111111111111111111011) Number of bit shifts: 2
Result: -2(11111111111111111111111111111110)

{BITWISE UNSIGNED RIGHT SHIFT OPERATION}
Input Number: 5(101) Number of bit shifts: 1
Result: 2(10)

{BITWISE UNSIGNED RIGHT SHIFT OPERATION}
Input Number: -5(11111111111111111111111111111011) Number of bit shifts: 2
Result: 1073741822(111111111111111111111111111110)

{BITWISE SET NTH BIT TO ZERO OPERATION}
Input Number: 5(101) Bit to set zero: 2
Result: 1(1)

{BITWISE SET NTH BIT TO ZERO OPERATION}
Input Number: -5(11111111111111111111111111111011) Bit to set zero: 1
Result: -7(11111111111111111111111111111001)

{BITWISE SET NTH BIT TO ONE OPERATION}
Input Number: 5(101) Bit to set one: 1
Result: 7(111)

{BITWISE SET NTH BIT TO ONE OPERATION}
Input Number: -5(11111111111111111111111111111011) Bit to set one: 2
Result: -1(11111111111111111111111111111111)