diff --git a/arith/Makefile b/arith/Makefile index c650405..4a6bfdc 100644 --- a/arith/Makefile +++ b/arith/Makefile @@ -1,4 +1,4 @@ -TARGETS = adder substractor multiplier divider negator comparator +TARGETS = adder substractor multiplier divider negator comparator shifter .PHONY: all clean @@ -18,4 +18,6 @@ divider: negator: gcc -I../common/ ../common/auxiliar.c negator.c -o negator comparator: - gcc -I../common/ ../common/auxiliar.c comparator.c -o comparator \ No newline at end of file + gcc -I../common/ ../common/auxiliar.c comparator.c -o comparator +shifter: + gcc -I../common/ ../common/auxiliar.c shifter.c -o shifter \ No newline at end of file diff --git a/arith/adder.c b/arith/adder.c index c890fa1..8fa1587 100644 --- a/arith/adder.c +++ b/arith/adder.c @@ -14,8 +14,6 @@ int check_length(char **inputs, uint8_t num_inputs) int main(int argc, char **argv) { - int i; - int pos; if(argc != 2) { error(); @@ -41,9 +39,9 @@ int main(int argc, char **argv) error(); } int a,b,carry_in,c; - a = bin2dec(inputs[0]); - b = bin2dec(inputs[1]); - carry_in = bin2dec(inputs[2]); + a = bin2udec(inputs[0]); + b = bin2udec(inputs[1]); + carry_in = bin2udec(inputs[2]); c = a+b+carry_in; char *result = dec2bin(c,input_length+1); printf("%s,%c",result+1,result[0]); diff --git a/arith/bit_adder.c b/arith/bit_adder.c new file mode 100644 index 0000000..9d7a80b --- /dev/null +++ b/arith/bit_adder.c @@ -0,0 +1,34 @@ +#include +#include +#include "auxiliar.h" + +int main(int argc, char **argv) +{ + if(argc != 2) + { + error(); + } + char *input = argv[1]; + if(!strcmp(input,"error")) + { + error(); + } + char **inputs = comma_separate(input); + if(inputs == NULL) + { + error(); + } + int num_inputs = num_occurrences(input,','); + if(num_inputs != 1) + { + error(); + } + int input_length = strlen(inputs[0]); + int num = bin2dec(inputs[0]); + num *= -1; + char *result = dec2bin(num,input_length); + printf("%s",result); + free(result); + free_mem(inputs,num_inputs); + return 0; +} diff --git a/arith/bit_finder.c b/arith/bit_finder.c new file mode 100644 index 0000000..9d7a80b --- /dev/null +++ b/arith/bit_finder.c @@ -0,0 +1,34 @@ +#include +#include +#include "auxiliar.h" + +int main(int argc, char **argv) +{ + if(argc != 2) + { + error(); + } + char *input = argv[1]; + if(!strcmp(input,"error")) + { + error(); + } + char **inputs = comma_separate(input); + if(inputs == NULL) + { + error(); + } + int num_inputs = num_occurrences(input,','); + if(num_inputs != 1) + { + error(); + } + int input_length = strlen(inputs[0]); + int num = bin2dec(inputs[0]); + num *= -1; + char *result = dec2bin(num,input_length); + printf("%s",result); + free(result); + free_mem(inputs,num_inputs); + return 0; +} diff --git a/arith/comparator.c b/arith/comparator.c index 4b6108f..90c90b8 100644 --- a/arith/comparator.c +++ b/arith/comparator.c @@ -2,6 +2,9 @@ #include #include "auxiliar.h" +#define SIGNED 1 +#define UNSIGNED 0 + int check_length(char **inputs, uint8_t num_inputs) { int input_length = strlen(inputs[0]); @@ -14,9 +17,8 @@ int check_length(char **inputs, uint8_t num_inputs) int main(int argc, char **argv) { - int i; - int pos; - if(argc != 2) + uint8_t signedness; + if(argc != 3) { error(); } @@ -25,6 +27,18 @@ int main(int argc, char **argv) { error(); } + if(!strcmp("unsigned", argv[2])) + { + signedness = UNSIGNED; + } + else if(!strcmp("signed", argv[2])) + { + signedness = SIGNED; + } + else + { + error(); + } char **inputs = comma_separate(input); if(inputs == NULL) { @@ -37,8 +51,16 @@ int main(int argc, char **argv) } int input_length = check_length(inputs,num_inputs); int a,b; - a = bin2dec(inputs[0]); - b = bin2dec(inputs[1]); + if(signedness == UNSIGNED) + { + a = bin2udec(inputs[0]); + b = bin2udec(inputs[1]); + } + else if(signedness == SIGNED) + { + a = bin2dec(inputs[0]); + b = bin2dec(inputs[1]); + } if(a > b) { printf("1,0,0"); diff --git a/arith/divider.c b/arith/divider.c index 163d93f..51dde77 100644 --- a/arith/divider.c +++ b/arith/divider.c @@ -18,8 +18,6 @@ int check_length(char **inputs, uint8_t num_inputs) int main(int argc, char **argv) { - int i; - int pos; if(argc != 2) { error(); @@ -51,8 +49,8 @@ int main(int argc, char **argv) memset(op,0x00,input_length+1); strcpy(op,upper); strcat(op,lower); - a = bin2dec(op); - b = bin2dec(inputs[2]); + a = bin2udec(op); + b = bin2udec(inputs[2]); c = a/b; rem = a%b; char *result = dec2bin(c,input_length); diff --git a/arith/multiplier.c b/arith/multiplier.c index 487d40f..e723a19 100644 --- a/arith/multiplier.c +++ b/arith/multiplier.c @@ -18,8 +18,6 @@ int check_length(char **inputs, uint8_t num_inputs) int main(int argc, char **argv) { - int i; - int pos; if(argc != 2) { error(); @@ -45,9 +43,9 @@ int main(int argc, char **argv) error(); } int a,b,carry_in,c; - a = bin2dec(inputs[0]); - b = bin2dec(inputs[1]); - carry_in = bin2dec(inputs[2]); + a = bin2udec(inputs[0]); + b = bin2udec(inputs[1]); + carry_in = bin2udec(inputs[2]); c = (a*b)+carry_in; char *result = dec2bin(c,input_length*2); printf("%s,%.*s",result+input_length,input_length,result); diff --git a/arith/negator.c b/arith/negator.c index 2166863..9d7a80b 100644 --- a/arith/negator.c +++ b/arith/negator.c @@ -4,8 +4,6 @@ int main(int argc, char **argv) { - int i; - int pos; if(argc != 2) { error(); diff --git a/arith/shifter.c b/arith/shifter.c new file mode 100644 index 0000000..d776617 --- /dev/null +++ b/arith/shifter.c @@ -0,0 +1,119 @@ +#include +#include +#include "auxiliar.h" + +#define LEFT 0 +#define RIGHT 1 +#define LOGIC 0 +#define ARITH 1 +#define ROTATE 2 + +int main(int argc, char **argv) +{ + uint8_t direction, type; + int shift; + if(argc != 3) + { + error(); + } + char *input = argv[1]; + if(!strcmp(input,"error")) + { + error(); + } + char **inputs = comma_separate(input); + if(inputs == NULL) + { + error(); + } + int num_inputs = num_occurrences(input,','); + if(num_inputs != 2) + { + error(); + } + int input_length = strlen(inputs[0]); + if(!strcmp("logic-left",argv[2])) + { + type = LOGIC; + direction = LEFT; + } + else if(!strcmp("logic-right",argv[2])) + { + type = LOGIC; + direction = RIGHT; + } + else if(!strcmp("arith-left",argv[2])) + { + type = ARITH; + direction = LEFT; + } + else if(!strcmp("arith-right",argv[2])) + { + type = ARITH; + direction = RIGHT; + } + else if(!strcmp("rotate-left",argv[2])) + { + type = ROTATE; + direction = LEFT; + } + else if(!strcmp("rotate-right",argv[2])) + { + type = ROTATE; + direction = RIGHT; + } + else + { + error(); + } + shift = bin2udec(inputs[1]); + while(shift >= input_length) + { + shift = shift % input_length; + } + char *result; + if(!shift) + { + result = inputs[0]; + } + else + { + if(type == LOGIC) + { + if(direction == LEFT) + { + result = dec2bin(bin2udec(inputs[0]) << shift,input_length); + } + else + { + result = dec2bin(bin2udec(inputs[0]) >> shift,input_length); + } + } + else if(type == ARITH) + { + if(direction == LEFT) + { + result = dec2bin(bin2dec(inputs[0]) << shift,input_length); + } + else + { + result = dec2bin(bin2dec(inputs[0]) >> shift,input_length); + } + } + else if(type == ROTATE) + { + if(direction == RIGHT) + { + shift = input_length - shift; + } + result = (char*) malloc(sizeof(char) * (input_length+1)); + memset(result,0x00,input_length); + strncpy(result,inputs[0]+shift,input_length-shift); + strncpy(result + (input_length-shift),inputs[0],shift); + } + } + printf("%s",result); + free(result); + free_mem(inputs,num_inputs); + return 0; +} diff --git a/arith/substractor.c b/arith/substractor.c index a89f120..d505406 100644 --- a/arith/substractor.c +++ b/arith/substractor.c @@ -14,8 +14,6 @@ int check_length(char **inputs, uint8_t num_inputs) int main(int argc, char **argv) { - int i; - int pos; if(argc != 2) { error(); @@ -42,9 +40,9 @@ int main(int argc, char **argv) } int a,b,borrow_in,c; char borrow_out = '0'; - a = bin2dec(inputs[0]); - b = bin2dec(inputs[1]); - borrow_in = bin2dec(inputs[2]); + a = bin2udec(inputs[0]); + b = bin2udec(inputs[1]); + borrow_in = bin2udec(inputs[2]); c = a-(b+borrow_in); if(c < 0) { diff --git a/common/auxiliar.c b/common/auxiliar.c index c2faea2..bda1aef 100644 --- a/common/auxiliar.c +++ b/common/auxiliar.c @@ -150,6 +150,27 @@ int bin2dec(char *bin) return num; } +int bin2udec(char *bin) +{ + int i; + int num = 0; + int length = strlen(bin); + int pos = length - 1; + char *aux = (char*) malloc(sizeof(char) * (length+1)); + memset(aux,0x00,length+1); + strcpy(aux,bin); + normalize(&aux,1); + for(i = 0; i < length; i++) + { + if(aux[pos--]) + { + num += 0x1 << i; + } + } + free(aux); + return num; +} + char* dec2bin(int dec, int length) { char *bin = (char*) malloc(sizeof(char) * (length + 1)); diff --git a/common/auxiliar.h b/common/auxiliar.h index e5dc34e..c787556 100644 --- a/common/auxiliar.h +++ b/common/auxiliar.h @@ -15,6 +15,7 @@ void free_mem(char **inputs, int num_inputs); void normalize(char **inputs, int num_inputs); int bin2dec(char *bin); +int bin2udec(char *bin); char* dec2bin(int dec, int length); void expand_input(char **input, int required_length); void reverse_two_complement(char *bin);