Last active
February 17, 2018 17:20
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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