1

I am writing a program that implements Booth's Algorithm to multiply ints. I am only allowed to use bit-level operators, logical operators, and bit shifts. I am allowed one loop for the program, and a function that will add two ints. I am having trouble understanding what is going wrong with my program. When I am using bitwise operators to mask half of the long long, I am getting incorrect values. Any advice on what I am doing wrong there? Maybe I am not understanding how to mask properly. It also may have to do with type casting; I am really unsure. Thanks in advance for any help!

Here is by code:

#include <stdio.h>

int Add (int x, int y);
long long Booth (int x, int y);

int main() {
    int hex1, hex2;
    long long product;
    printf("\nEnter Multiplicand & Multiplier in hex: ");
    scanf(" %x %x", &hex1, &hex2);

    product = Booth(hex1, hex2);

    printf("Multiplicand = 0x%08X \tAs signed = %+d\n", hex1, hex1);
    printf("Multiplier = 0x%08X \tAs signed = %+d\n", hex2, hex2);
    printf("Product = 0x%16X \tAs signed = %+d\n", product, product);
}

int Add (int x, int y) {
    return x + y;
}

long long Booth (int multiplicand, int multiplier) {
    int i;
    long long product;
    long long productLH;
    long long productRH;
    int productLHI;
    int productRHI;
    int cOut;
    int negMultiplicand;
    negMultiplicand = Add (~multiplicand, 1);
    product = (long long) Add (0, multiplier);

    for (i = 0; i < 32; i++) {
        if (((product & 1) == 1) && (cOut == 0)) {
            //Mask left half and right half of product
            productLH = (product & 0xFFFFFFFF00000000);
            productRH = (product & 0x00000000FFFFFFFF);

            //Bit shift product so all values are in lower 32 bits
            productLH = (productLH >> 32);

            //Convert left halves and right halves to ints
            productLHI = (int) (productLH & 0x00000000FFFFFFFF);
            productRHI = (int) productRH & (0x00000000FFFFFFFF);
            productLHI = Add(productLHI, negMultiplicand);

            //Put halves back together
            product = (long long) Add(productLHI, 0);
            product = ((product << 32) & 0xFFFFFFFFFFFFFFFF);
            product = (long long) Add((int)product, productRHI);
        }   
        else if (((product & 1) == 0) && (cOut == 1)) {
            //Mask left half and right half of product
            productLH = (product & 0xFFFFFFFF00000000);
            productRH = (product & 0x00000000FFFFFFFF);

            //Bit shift product so all values are in lower 32 bits
            productLH = (productLH >> 32);

            //Convert left halves and right halves to ints
            productLHI = (int) (productLH & 0x00000000FFFFFFFF);
            productRHI = (int) productRH & (0x00000000FFFFFFFF);
            productLHI = Add(productLHI, multiplicand);

            //Put halves back together
            product = (long long) Add(productLHI, 0);
            product = ((product << 32) & 0xFFFFFFFFFFFFFFFF);
            product = (long long) Add((int)product, productRHI);
        }
        cOut = (product & 1);
        product = product >> 1;
    }
    return product;
}
Armali
  • 18,255
  • 14
  • 57
  • 171
MrNinjaSox
  • 11
  • 2
  • You should use the correct format specifier for `long long`: `%lld` (or `%llX` for hex). Besides, `produceCopy1` is not defined; also `cOut` is read before it gets initialized. – rslemos Feb 17 '16 at 03:59
  • You have to initialize it to what value is sane for your algorithm. Is it zero? Then `int cOut = 0;`. – rslemos Feb 17 '16 at 04:00
  • I have done that, and my problem still is not solved. Thank you though for noticing that, I didn't see that when I looked at it. I believe the error is something with my bit masking and type casting. I am not sure what is wrong with that though. – MrNinjaSox Feb 17 '16 at 04:07
  • Bit shifts on signed values are problematic. See [**Arithmetic bit-shift on a signed integer**](http://stackoverflow.com/questions/4009885/arithmetic-bit-shift-on-a-signed-integer) – David C. Rankin Feb 17 '16 at 05:03
  • Make all your types be unsigned, and use `ULL` suffix on your hex constants – M.M Apr 12 '16 at 07:00

3 Answers3

0

Return of function Add() may not be integer type but you are returning int type. If we add two integers may result more than int type.

Aditya B G
  • 21
  • 3
0

You don't need those masks to solve the problem. If the masking is the problem, just bitwise or the product and the multiplier, which will set the lower 32 bits of the 64 bit product to the "right half" you want. Then, just pass the product shifted 32 bits to the right, cast to an int in your addition function call. This will truncate the 64 bit binary to 32 bit binary.

PS. Starting Babic's lab assignments the night before ensures you're going to be in for a bad time...

0

In addition to the errors rslemos noticed, there are still two things to correct:

  1. The integer constants 0xFFFFFFFF00000000 and 0xFFFFFFFFFFFFFFFF need a suffix with LL.
  2. When adding something to product, the value added must not sign-extend. Thus, change

        product = (long long) Add (0, multiplier);
    

    to

        product = (unsigned)multiplier; // do not sign-extend multiplier
    

    and

                product = (long long) Add((int)product, productRHI);
    

    to

                product |= (unsigned)productRHI;    // do not sign-extend productRHI
    

    (two occurrences).

Armali
  • 18,255
  • 14
  • 57
  • 171