Skip to content

Instantly share code, notes, and snippets.

@meetmangukiya
Last active February 17, 2018 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meetmangukiya/ed0ccfdc9d715ef37d0ef95a5fe34250 to your computer and use it in GitHub Desktop.
Save meetmangukiya/ed0ccfdc9d715ef37d0ef95a5fe34250 to your computer and use it in GitHub Desktop.
Booths algorithm implementation in C, for results of maximum 63 bits, since 64th bit is the sign bit.
#include "binary.h"
#include <stdio.h>
#include <math.h>
#define MAX_BIN_LEN 64
/*
* Takes two binary numbers, adds them and stores the result in res.
*/
void add_binary(struct binary* num1, struct binary* num2, struct binary* res)
{
struct binary* greater;
struct binary* smaller;
if (num1->size > num2->size)
{
greater = num1;
smaller = num2;
}
else
{
greater = num2;
smaller = num1;
}
int carry = 0;
int i;
for(i = 0; i < greater->size; i++)
{
struct adder_result hadd_res;
if (i < smaller->size)
{
hadd_res = full_adder(greater->array[i],
smaller->array[i],
carry);
}
else
{
hadd_res = full_adder(greater->array[i],
0,
carry);
}
carry = hadd_res.carry;
res->array[i] = hadd_res.res;
}
res->size = i;
}
/*
* Converts given number to binary and stores the result in bin
*/
void decimal_to_binary(int num, struct binary* res)
{
if (num > 0)
{
int count = 0;
while(num > 0)
{
res->array[count++] = num % 2;
num /= 2;
}
// Sign bit
res->array[count++] = 0;
res->size = count;
}
else
{
num *= -1;
decimal_to_binary(num, res);
twos_complement(res, res);
}
}
/*
* Extends given binary number to bitsize size, i.e. add leading zeros.
*/
void extend_bits(struct binary* bin, int size)
{
int bit = bin->array[bin->size - 1];
for(int i = bin->size; i < size; i++)
{
bin->array[bin->size++] = bit;
}
}
/*
* Prints the given binary number.
*/
void print_binary(struct binary* bin)
{
for(int i = bin->size - 1; i >= 0; i--)
printf("%d", bin->array[i]);
}
/*
* Multiplies two binary numbers.
*/
void multiply_binary(struct binary* multiplicand, struct binary* multiplier,
struct binary* result)
{
int i;
int q0 = 0;
int accumulator_arr[MAX_BIN_LEN];
struct binary accumulator;
accumulator.size = multiplier->size;
accumulator.array = accumulator_arr;
// initialise accumulator to 0
for(i = 0; i < accumulator.size; i++)
accumulator.array[i] = 0;
struct binary twos_c_micand;
twos_c_micand.size = multiplicand->size;
int twos_c_arr[MAX_BIN_LEN];
twos_c_micand.array = twos_c_arr;
twos_complement(multiplicand, &twos_c_micand);
for(i = 0; i < multiplier->size; i++)
{
if (multiplier->array[0] == 1 && q0 == 0)
{
add_binary(&accumulator, &twos_c_micand, &accumulator);
}
else if (multiplier->array[0] == 0 && q0 == 1)
{
add_binary(&accumulator, multiplicand, &accumulator);
}
q0 = arithmetic_right_shift(multiplier);
int tmp = arithmetic_right_shift(&accumulator);
multiplier->array[multiplier->size - 1] = tmp;
}
int j = 0;
for(i = 0; i < multiplier->size; i++)
result->array[j++] = multiplier->array[i];
for(i = 0; i < accumulator.size; i++)
result->array[j++] = accumulator.array[i];
result->size = j;
}
/*
* Computes ones complement of given binary number and stores result in res.
*/
void ones_complement(struct binary* num, struct binary* res)
{
int i;
for(i = 0; i < num->size; i++)
{
if (num->array[i] == 0)
res->array[i] = 1;
else
res->array[i] = 0;
}
res->size = num->size;
}
/*
* Computes twos complement of given binary number and stores result in result.
*/
void twos_complement(struct binary* num, struct binary* res)
{
struct binary one;
one.size = 1;
int onearr[1] = {1};
one.array = onearr;
ones_complement(num, res);
add_binary(res, &one, res);
}
/*
* Takes given binary number and performs a arithmetic right shift and returns
* the popped out LSB.
*/
int arithmetic_right_shift(struct binary* num)
{
int i;
int retval = num->array[0];
for(i = 0; i < num->size - 1; i++)
num->array[i] = num->array[i+1];
return retval;
}
/*
* Takes given binary number, converts to decimal and return its value.
*/
int binary_to_decimal(struct binary* bin)
{
int sign = 0;
if (bin->array[bin->size - 1] == 1)
{
struct binary res;
int res_arr[MAX_BIN_LEN];
res.array = res_arr;
twos_complement(bin, &res);
bin = &res;
sign = 1;
}
int sum = 0;
for(int i = 0; i < bin->size - 1; i++)
{
if (bin->array[i] == 1)
sum += (int)pow(2, i);
}
if (sign == 1)
sum *= -1;
return sum;
}
/*
* Takes given decimal number and computes the number of bits required to
* represent the number.
*/
int bit_size(int num)
{
int count = 0;
if (num < 0)
num *= -1;
while (num > 0)
{
num /= 2;
count++;
}
return count;
}
/*
* Multiplies two integers and returns the result.
*/
int multiply_int(int num1, int num2)
{
struct binary multiplicand;
struct binary multiplier;
struct binary res;
int micand_arr[MAX_BIN_LEN];
int mier_arr[MAX_BIN_LEN];
int res_arr[MAX_BIN_LEN];
multiplicand.array = micand_arr;
multiplier.array = mier_arr;
res.array = res_arr;
res.size = MAX_BIN_LEN;
decimal_to_binary(num1, &multiplicand);
decimal_to_binary(num2, &multiplier);
extend_bits(&multiplicand, multiplier.size);
extend_bits(&multiplier, multiplicand.size);
multiply_binary(&multiplicand, &multiplier, &res);
return binary_to_decimal(&res);
}
/*
* Takes two bits, a carry and performs a full addition.
*/
struct adder_result full_adder(int bit1, int bit2, int carry)
{
struct adder_result res;
res.carry = ((bit1 & bit2) | (bit2 & carry) | (bit1 & carry));
res.res = ((bit1 & !bit2 & !carry) | (!bit1 & !bit2 & carry) |
(bit1 & bit2 & carry) | (!bit1 & bit2 & !carry));
return res;
}
#ifndef BINARY_H
#define BINARY_H
#define MAX_BIN_LEN 64
struct binary {
int* array;
int size;
};
struct adder_result {
int res;
int carry;
};
void add_binary(struct binary* num1, struct binary* num2, struct binary* res);
void decimal_to_binary(int, struct binary*);
void extend_bits(struct binary* bin, int size);
void print_binary(struct binary* bin);
void multiply_binary(struct binary* num1, struct binary* num2, struct binary* res);
void ones_complement(struct binary* num, struct binary* res);
void twos_complement(struct binary* num, struct binary* res);
int arithmetic_right_shift(struct binary* num);
int binary_to_decimal(struct binary*);
int bit_size(int num);
int multiply_int(int num1, int num2);
struct adder_result full_adder(int bit1, int bit2, int carry);
#endif
#include <stdio.h>
#include <math.h>
#include "binary.h"
int main()
{
int micand, mier;
printf("Enter multiplicand, multiplier: ");
scanf("%d%d", &micand, &mier);
int res = multiply_int(micand, mier);
printf("Result: %d", res);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment