Header Ads Widget

Responsive Advertisement

Addition and subtraction by using Shift operator

Understanding of Bitwise operator

Let's break down the concepts and examples you provided into a structured explanation, with a focus on addition and subtraction using bitwise operations, Booth's Algorithm, and recursive methods.

1. Bitwise Operations

Bitwise operations work directly on the binary representations of numbers. These operations include OR (|), AND (&), XOR (^), and NOT (~), among others. Let's briefly go over each:

a. Bitwise OR (|)

  • Operation: Returns 1 if either of the corresponding bits is 1.
  • Example:

text

a = 5  (Binary: 0101)

b = 7  (Binary: 0111)

 

a | b  = 0111  (Decimal: 7)

 

b. Bitwise AND (&)

  • Operation: Returns 1 if both corresponding bits are 1.
  • Example:

text

a = 5  (Binary: 0101)

b = 7  (Binary: 0111)

 

a & b  = 0101  (Decimal: 5)

 

c. Bitwise XOR (^)

  • Operation: Returns 1 if corresponding bits are different.
  • Example:

text

a = 5  (Binary: 0101)

b = 7  (Binary: 0111)

 

a ^ b  = 0010  (Decimal: 2)

 

d. Bitwise NOT (~)

  • Operation: Inverts all the bits (i.e., 0s become 1s, and 1s become 0s).
  • Example:

text

a = 5  (Binary: 0101)

 

~a = 1010 (This is the one's complement)

 

  • Note: The result can be treated as a negative number in 2's complement form.

e. Left Shift (<<)

  • Operation: Shifts bits to the left, filling with 0s.
  • Example:

text

a = 5  (Binary: 00000101)

a << 1  = 00001010  (Decimal: 10)

 

f. Right Shift (>>)

  • Operation: Shifts bits to the right. The sign bit (leftmost bit) is preserved for signed numbers.
  • Example:

text

b = -10  (Binary: 11110110)

b >> 1  = 11111011  (Decimal: -5)

 

2. Addition and Subtraction Using Bitwise Operations

Addition with Bitwise Operations

  • The sum of two numbers can be computed using bitwise operations.
  • Algorithm:
    1. XOR the numbers to get the sum without carrying.
    2. AND the numbers and left shift by 1 to get the carry.
    3. Repeat the process until the carry is 0.
  • Example:

java

int add(int a, int b) {

    while (b != 0) {

        int carry = a & b;

        a = a ^ b;

        b = carry << 1;

    }

    return a;

}

 

Subtraction with 2's Complement

  • Subtraction can be treated as the addition of a number and the 2's complement of another.
  • Steps:
    1. Find the 2's complement of the subtrahend.
    2. Add the result to the minuend using the above addition algorithm.
  • Example:
    • To subtract b from a, calculate a + (-b), where -b is the 2's complement of b.

3. Booth's Algorithm

  • Purpose: Booth's algorithm is used for multiplying binary numbers efficiently, especially when one number is negative.
  • Process:
    1. Convert the multiplicand and multiplier to binary.
    2. Use the Booth's encoding to handle negative numbers.
    3. Multiply using bit shifts and additions based on the Booth's algorithm rules.
  • Application in Subtraction:
    • Subtraction in Booth's algorithm involves finding the 2's complement of the subtrahend.

4. Recursive Method for Subtraction

  • Concept: Recursion can be used to subtract two numbers by reducing the problem step by step.
  • Example:

java

int subtract(int a, int b) {

    if (b == 0)

        return a;

    return subtract(a ^ b, (~a & b) << 1);

}

 

    • The base case is when b is 0, at which point a contains the result.
    • The recursive step involves XORing a and b to simulate subtraction and computing the borrow with AND and shift.

5. Examples of Adding Positive and Negative Numbers

Example 1: Adding Positive and Negative Values

  • Positive + Positive Example:
    • 1101 + 0111 = 1 0100
    • Discard the carry to get 0100 as the result.

Example 2: Positive + Negative

  • When the negative number has a higher magnitude:
    • 1101 + (-1110)
    • Find the 2's complement of 1110.
    • Add the positive number to this 2's complement.

6. Conclusion

  • Bitwise operations offer powerful tools for arithmetic, especially in low-level programming and algorithms like Booth's.
  • The combination of bitwise operations and recursive methods allows for efficient implementation of addition and subtraction, even with negative numbers.

This explanation provides an overview of how addition and subtraction can be implemented using various techniques, focusing on bitwise operations, Booth's algorithm, and recursive methods.

 

Now Problem statement solved by Bitwise operator

 

1. Overview of the Code

The provided Java program includes methods to perform addition (getSum) and subtraction (subtract) without using the traditional arithmetic operators (+ and -). Instead, it leverages bitwise operations and recursion to achieve these operations. Here's a breakdown of the main components:

a. getSum Method

java

public static int getSum(int p, int q) {

    int result = p ^ q; // Sum without carry

    int carry = (p & q) << 1; // Carry bits

    if (carry != 0) {

        return getSum(result, carry); // Recursive call

    }

    return result;

}

 

  • Purpose: Computes the sum of two integers p and q without using the + operator.
  • Mechanism:
    • XOR (^): Adds the bits of p and q where at least one of the bits is 1 but not both. This effectively adds the numbers without considering the carry.
    • AND (&) and Left Shift (<<): Identifies the carry bits by performing an AND operation and then shifting the result left by one to represent the carry's actual position.
    • Recursion: Continues adding the result and carry until there are no carry bits left (carry == 0).

b. subtract Method

java

public static int subtract(int n1, int n2){

    // Add two's complement of n2 to n1

    return getSum(n1, getSum(~n2, 1));

}

 

  • Purpose: Subtracts integer n2 from n1 without using the - operator.
  • Mechanism:
    • Two's Complement: Converts n2 to its two's complement by first applying the bitwise NOT (~) to get the one's complement and then adding 1. This effectively represents -n2.
    • Addition: Uses the getSum method to add n1 and the two's complement of n2, resulting in n1 - n2.

c. main Method

java

public static void main(String[] args) {

    int i = 10;

    int j = 12;

    int r = getSum(i, j);

    System.out.println(r); // Outputs: 22

    int r1 = subtract(j, i);

    System.out.println(r1); // Outputs: 2

}

 

  • Functionality: Demonstrates the usage of getSum and subtract methods by adding and subtracting two integers.

 

2. Detailed Explanation of Bitwise Operations

a. Bitwise XOR (^)

  • Operation: Compares each bit of two numbers and returns 1 if the bits are different, else 0.
  • Usage in getSum: Adds the numbers without considering the carry.

Example:

text

p = 5 (0101)

q = 3 (0011)

p ^ q = 0110 (6)

 

b. Bitwise AND (&)

  • Operation: Compares each bit of two numbers and returns 1 only if both bits are 1.
  • Usage in getSum: Identifies the carry bits.

Example:

text

p = 5 (0101)

q = 3 (0011)

p & q = 0001 (1)

 

c. Left Shift (<<)

  • Operation: Shifts all bits in a number to the left by a specified number of positions, filling with 0s.
  • Usage in getSum: Positions the carry bits correctly for the next addition step.

Example:

text

carry = 0001

carry << 1 = 0010 (2)

 

d. Bitwise NOT (~)

  • Operation: Inverts all bits in a number (0 becomes 1 and 1 becomes 0).
  • Usage in subtract: Creates the one's complement of n2 to form its two's complement.

Example:

text

n2 = 5 (0101)

~n2 = 1010

 

 

3. Recursion in getSum

Recursion in the getSum method continues to add the result and carry until there are no carry bits left. This mimics the process of adding binary numbers manually, where you add the bits and carry over any overflow to the next higher bit.

Example Walkthrough:

Let's add 5 and 3 using getSum:

  1. First Call:
    • p = 5 (0101)
    • q = 3 (0011)
    • result = p ^ q = 0110 (6)
    • carry = (p & q) << 1 = 0001 << 1 = 0010 (2)
    • Since carry != 0, make a recursive call with result = 6 and carry = 2.
  2. Second Call:
    • p = 6 (0110)
    • q = 2 (0010)
    • result = p ^ q = 0100 (4)
    • carry = (p & q) << 1 = 0010 << 1 = 0100 (4)
    • Since carry != 0, make another recursive call with result = 4 and carry = 4.
  3. Third Call:
    • p = 4 (0100)
    • q = 4 (0100)
    • result = p ^ q = 0000 (0)
    • carry = (p & q) << 1 = 0100 << 1 = 1000 (8)
    • Since carry != 0, make another recursive call with result = 0 and carry = 8.
  4. Fourth Call:
    • p = 0 (0000)
    • q = 8 (1000)
    • result = p ^ q = 1000 (8)
    • carry = (p & q) << 1 = 0000 << 1 = 0000 (0)
    • Since carry == 0, return result = 8.
  5. Back to Third Call:
    • Receive 8 from the fourth call and return 8.
  6. Back to Second Call:
    • Receive 8 from the third call and return 8.
  7. Back to First Call:
    • Receive 8 from the second call and return 8.

Final Result: 5 + 3 = 8

 

4. Relation to Booth's Algorithm

a. What is Booth's Algorithm?

Booth's Algorithm is a multiplication algorithm that multiplies two signed binary numbers in two's complement notation. It reduces the number of addition and subtraction operations required by encoding the multiplier to minimize the number of operations.

b. How Does Your Code Relate to Booth's Algorithm?

While your code focuses on addition and subtraction using bitwise operations and recursion, these operations are fundamental to Booth's Algorithm. Here's how they interconnect:

  1. Addition and Subtraction:
    • Booth's Algorithm relies heavily on adding and subtracting partial products. Your getSum and subtract methods provide the necessary tools for these operations without using the + or - operators.
  2. Handling Negative Numbers:
    • Booth's Algorithm deals with negative numbers using two's complement representation. Your subtract method demonstrates how to compute the two's complement, which is essential for handling negative multiplicands or multipliers in Booth's Algorithm.
  3. Bitwise Operations:
    • Both your methods and Booth's Algorithm utilize bitwise operations (AND, OR, XOR, NOT, and shifts) to perform arithmetic operations efficiently at the binary level.

c. Implementing Booth's Algorithm Using Your Methods

To extend your current implementation towards Booth's Algorithm, you would need to:

  1. Multiply Two Numbers:
    • Use your getSum method to add partial products.
    • Handle the shifting and encoding of the multiplier as per Booth's rules.
  2. Optimize Multiplication:
    • Reduce the number of additions by encoding the multiplier to identify sequences of 1s and 0s, thus minimizing the required operations.
  3. Handle Signed Multiplication:
    • Ensure that the two's complement representation is correctly used for negative numbers during multiplication.

 

5. Enhancements and Best Practices

While your implementation is effective for basic addition and subtraction, here are some suggestions to enhance it further:

a. Handling Overflow

  • Issue: The current implementation does not handle integer overflow, which can lead to incorrect results for large numbers.
  • Solution: Implement checks to detect when the sum exceeds the maximum or minimum value an int can hold in Java (Integer.MAX_VALUE and Integer.MIN_VALUE).

b. Iterative Approach for Efficiency

  • Issue: Recursive calls can lead to stack overflow for large numbers due to deep recursion.
  • Solution: Convert the recursive getSum method to an iterative one to improve efficiency and prevent potential stack overflow errors.

Iterative getSum Example:

java

public static int getSumIterative(int p, int q) {

    while (q != 0) {

        int carry = p & q;

        p = p ^ q;

        q = carry << 1;

    }

    return p;

}

 

c. Extending to Multiplication (Booth's Algorithm)

  • Implementation: Based on your current methods, you can implement Booth's Algorithm to perform multiplication. This would involve encoding the multiplier and using the getSum method to accumulate partial products efficiently.

Booth's Algorithm Skeleton:

java

public static int boothMultiply(int multiplicand, int multiplier) {

    // Initialize variables

    int product = 0;

    int m = multiplicand;

    int q = multiplier;

    int n = Integer.SIZE; // Number of bits

 

    for (int i = 0; i < n; i++) {

        // Check the last bit of q

        if ((q & 1) == 1) {

            product = getSum(product, m);

        }

        // Arithmetic shift right by 1

        q = q >> 1;

        m = m << 1;

    }

    return product;

}

 

Note: This is a simplified version. A complete implementation would handle encoding based on Booth's rules and manage negative numbers appropriately.

d. Improving subtract Method

  • Issue: The current subtract method relies on recursion indirectly through getSum. While effective, it can be optimized.
  • Solution: Use an iterative approach similar to getSumIterative for subtraction to enhance performance.

Iterative subtract Example:

java

public static int subtractIterative(int n1, int n2) {

    return getSumIterative(n1, getSumIterative(~n2, 1));

}

 

6. Complete Enhanced Code Example

Integrating the above enhancements, here's an improved version of your Java program:

java

package com.kartik;

 

/**

 *

 * @author kartik

 * Enhanced Addition and Subtraction Algorithms with Bitwise Operations

 */

 

public class AdditionAndSubtraction {

 

    /**

     * Adds two integers using bitwise operations (iterative approach).

     * @param p First integer

     * @param q Second integer

     * @return Sum of p and q

     */

    public static int getSum(int p, int q) {

        while (q != 0) {

            int carry = p & q; // Carry bits

            p = p ^ q;         // Sum without carry

            q = carry << 1;    // Carry shifted left

        }

        return p;

    }

 

    /**

     * Subtracts the second integer from the first using bitwise operations.

     * @param n1 Minuend

     * @param n2 Subtrahend

     * @return Difference of n1 and n2

     */

    public static int subtract(int n1, int n2){

        // Subtraction: n1 - n2 = n1 + (~n2 + 1)

        return getSum(n1, getSum(~n2, 1));

    }

 

    /**

     * Multiplies two integers using Booth's Algorithm.

     * @param multiplicand First integer

     * @param multiplier Second integer

     * @return Product of multiplicand and multiplier

     */

    public static int boothMultiply(int multiplicand, int multiplier) {

        int product = 0;

        int m = multiplicand;

        int q = multiplier;

        int n = Integer.SIZE; // Number of bits

 

        for (int i = 0; i < n; i++) {

            if ((q & 1) == 1) {

                product = getSum(product, m);

            }

            // Arithmetic shift right

            q = q >> 1;

            m = m << 1;

        }

        return product;

    }

 

    public static void main(String[] args) {

        int i = 10;

        int j = 12;

 

        // Addition

        int sum = getSum(i, j);

        System.out.println("Sum of " + i + " and " + j + " is: " + sum); // Outputs: 22

 

        // Subtraction

        int difference = subtract(j, i);

        System.out.println("Difference of " + j + " and " + i + " is: " + difference); // Outputs: 2

 

        // Multiplication using Booth's Algorithm

        int product = boothMultiply(i, j);

        System.out.println("Product of " + i + " and " + j + " is: " + product); // Outputs: 120

    }

}

 

7. Conclusion

Your implementation effectively demonstrates how fundamental bitwise operations and recursion can be harnessed to perform basic arithmetic operations without relying on traditional operators. By understanding and utilizing these low-level operations, you not only gain deeper insights into how arithmetic is handled at the binary level but also pave the way for implementing more complex algorithms like Booth's Algorithm for efficient multiplication.

Key Takeaways:

  • Bitwise Operations: Powerful tools for manipulating binary data, essential for low-level programming and optimization.
  • Recursion vs. Iteration: While recursion offers elegant solutions, iterative approaches can enhance performance and prevent issues like stack overflow.
  • Two's Complement: A widely used method for representing signed integers, facilitating easy implementation of subtraction and handling negative numbers.
  • Algorithm Efficiency: Understanding and implementing algorithms like Booth's can lead to more efficient computational methods, especially in systems where performance is critical.

Feel free to further expand your program by implementing additional algorithms or optimizing existing methods to handle a wider range of scenarios and input values.

  


Sum with bit operator
Sum with bit operator


substraction with bit operator
substraction with bit operator
division with bit operator
division with bit operator

multiplication with bit operator
multiplication with bit operator







Post a Comment

0 Comments