Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Write these programs in C ONLY This assignment is designed to help you learn the

ID: 3854711 • Letter: W

Question

Write these programs in C ONLY

This assignment is designed to help you learn the representation, interpretation, and manipulation of data in its internal representation. There are two parts. In the first part, you will implement a program calc to add and subtract numbers specified in different bases (multiplication is extra credit). In the second part, you will implement a program format that will print the decimal values of bit sequences representing integer and floating point data types. 2 Numeric Base Conversion and Calculator Implement a program called calc with the following usage interface: calc The first argument, , is either the string "+", for addition, or "-", for subtraction. If you want to implement multiplication, then can also be the string". (If you do implement multiplication, make sure to say so in your readme.pdf file so that the TAs know to check your program for this functionality.) The next two arguments, and are 64-bit, two's-complement integers. Each of these numbers will be given in the form of: which can be interpreted as: a base indicator where b means that the number is a binary number, o means octal, r means hexadecimal and d means decimal. dndn-1...dido are the digits of the number. A decimal number may be preceded by a minus sign. Note that a minus sign is neither meaningful nor necessary for binary, octal or hexadecimal numbers as the bit pattern for these representations already covers positive and negative quantities. The final argument, , gives the base for the resulting output number. Like the base indicator for the input numbers, this argument can be one of four strings: "b" for binary, "o" for octal, "d" for decimal, and "r" for hexadecimal. Your program should output the answer in the same form as the input numbers (that is, the output number should follow the regular expression given above) Some examples

Explanation / Answer

calc.c

#include "calc.h"

/* minimum required number of parameters */
#define MIN_REQUIRED 5

/* display usage */
void help(char* error) {
#ifdef DEBUG
   printf("IN HELP ");
#endif
   printf("%s ", error);
   printf("Usage: ./calc <OPTIONS> <OPTIONS> [-h] help [argument] <op> <number1> <number2> <output base> ");
   exit(EXIT_FAILURE);
#ifdef DEBUG
   printf("OUT HELP ");
#endif
}

int main ( int argc, char **argv ) {
   double time_spent;
   clock_t tic=clock(), toc;
#ifdef DEBUG
   printf("IN MAIN ");
#endif
   /*Displays Help Command*/

   if(argc!=MIN_REQUIRED) {   help("WRONG NUMBER OF ARGUMENTS");}
   if(!strcmp(argv[1], "-h")){   help("HELP: ");}
   if(argc == 5){   checkArgs(argv[1], argv[2], argv[3], argv[4]);}

   if(!strcmp(argv[1], "+")){   add(argv[2], argv[3], argv[4]);   }
   if(!strcmp(argv[1], "-")){   subs(argv[2], argv[3], argv[4]);}
   if(!strcmp(argv[1], "*")){   mult(argv[2], argv[3], argv[4]);}

   toc = clock();
   time_spent=(double)(toc-tic)/CLOCKS_PER_SEC;
   time_spent=time_spent/1000000;
#ifdef DEBUG
   printf(" ========= TIME SPENT: %.032f ========= ", time_spent);
#endif
#ifdef DEBUG
   printf("OUT OF MAIN ");
#endif
   return 0;
}

/*Checks arguments for validity*/
void checkArgs(char* arg1, char* arg2, char* arg3, char* arg4){
   int i;
#ifdef DEBUG
   printf("IN ARG CHECK ");
#endif
   /*check for correct operation*/
   if(arg1[0] != '+' && arg1[0] != '-' && arg1[0] != '*'){
       help("WRONG OPERATION");
   }
   if(arg2[0] == '-'){
       arg2 = removeFirst(arg2);
   }
   if(arg3[0] == '-'){
       arg3 = removeFirst(arg3);
   }
   /*check for number and base validity for first number*/
   switch(arg2[0]){
       case 'b':
           for(i=1; i<strlen(arg2); i++){
               if(arg2[i] != '1' && arg2[i] != '0')
                   help("INVALID BINARY NUMBER");
           }
           break;
       case 'd':
           for(i=1; i<strlen(arg2); i++){
               if((int)arg2[i] > (int)'9' || (int)arg2[i] < (int)'0'){
                   help("INVALID DECIMAL NUMBER");
               }
           }
           break;
       case 'x':
           for(i=1; i<strlen(arg2); i++){
               if((int)arg2[i] > (int)'9' || (int)arg2[i] < (int)'0' ){
                   if((int)arg2[i] < (int)'A' || (int)arg2[i] > (int)'F')
                       help("INVALID HEXADECIMAL NUMBER");
               }
           }
           break;
       case 'o':
           for(i=1; i<strlen(arg2); i++){
               if((int)arg2[i] > (int)'7' || (int)arg2[i] < (int)'0'){
                   help("INVALID OCTAL NUMBER");
               }
           }
           break;
       default:
           help("WRONG INPUT BASE");
   }
   /*check for number and base validity for second number*/
   switch(arg3[0]){
       case 'b':
           for(i=1; i<strlen(arg3); i++){
               if(arg3[i] != '1' && arg3[i] != '0')
                   help("INVALID BINARY NUMBER");
           }
           break;
       case 'd':
           for(i=1; i<strlen(arg3); i++){
               if((int)arg3[i] > (int)'9' || (int)arg3[i] < (int)'0'){
                   help("INVALID DECIMAL NUMBER");
               }
           }
           break;
       case 'x':
           for(i=1; i<strlen(arg3); i++){
               if((int)arg3[i] > (int)'9' || (int)arg3[i] < (int)'0' ){
                   if((int)arg3[i] < (int)'A' || (int)arg3[i] > (int)'F')
                       help("INVALID HEXADECIMAL NUMBER");
               }
           }
           break;
       case 'o':
           for(i=1; i<strlen(arg3); i++){
               if((int)arg3[i] > (int)'7' || (int)arg3[i] < (int)'0'){
                   help("INVALID OCTAL NUMBER");
               }
           }
           break;
       default:
           help("WRONG INPUT BASE");
   }
   /*printf("ARG4: %s ", arg4);*/

   /*check for correct output base*/
   if(arg4[0] != 'b' && arg4[0] != 'd' && arg4[0] != 'o' && arg4[0] != 'x'){
       help("INVALID OUTPUT BASE");
   }
   if(arg4[1] != ''){
       help("INVALID OUTPUT BASE");
   }
#ifdef DEBUG
   printf("OUT ARG CHECK ");
#endif
   return;
}

/*Add the numbers*/
void add(char* number1, char* number2, char* outbase){
   struct number * num1 = parseNum(number1);
   struct number * num2 = parseNum(number2);
   signed long int total=0, dec1, dec2;
   char * totalBin;
   char * totalHex;
   char * totalOct;
#ifdef DEBUG
   printf("IN ADD ");
#endif
   dec1 = num1->negative == true ? num1->decimal*(-1): num1->decimal;
#ifdef DEBUG
   printf("DECIMAL 1: %ld ", dec1);
#endif
   dec2 = num2->negative == true ? num2->decimal*(-1): num2->decimal;
#ifdef DEBUG
   printf("DECIMAL 2: %ld ", dec2);
#endif
   total = dec1 + dec2;
   /*printf("%ld %ld ", total, total*(-1));*/
   totalBin = total>0 ? conDecToBin(total): conDecToBin(total*(-1));
   /*total>0 ? printf("LEFT "): printf("RIGHT");*/
   /*
       if(total>0)
       totalHex = conDecToHex(total);
       else
       totalHex = conDecToHex(total*(-1));
       */
   totalHex = total>0 ? conDecToHex(total): conDecToHex(total*(-1));
   totalOct = total>0 ? conDecToOct(total): conDecToOct(total*(-1));

   /*   totalHex = total>0 ? conDecToHex(total): conDecToHex(total*(-1));*/
   /*printf("%s ", conDecToHex(total));*/
   printf(" ************************ THE SUM OF %s", num1->original);
   printf(" AND %s ", num2->original);
   total>0 ? printf("IS: BINARY: %s ", totalBin): printf("IS: BINARY: (-)%s ", totalBin);
   printf("DECIMAL: %li ", total);
   total>0 ? printf("HEXADECIMAL: %s ", totalHex): printf("HEXADECIMAL: (-)%s ", totalHex);
   total>0 ? printf("OCTAL:%s ************************ ", totalOct): printf("OCTAL: (-)%s ************************ ", totalOct);
#ifdef DEBUG
   printf("OUT ADD ");
#endif

}

/*Substract the numbers*/
void subs(char* number1, char* number2, char* outbase){
   struct number *num1 = parseNum(number1);
   struct number *num2 = parseNum(number2);
   signed long int total=0, dec1, dec2;
   char * totalBin;
   char * totalHex;
   char * totalOct;
#ifdef DEBUG
   printf("IN SUBTRACT ");
#endif
   dec1 = num1->negative == true ? num1->decimal*(-1): num1->decimal;
#ifdef DEBUG
   printf("DECIMAL 1: %ld ", dec1);
#endif
   dec2 = num2->negative == true ? num2->decimal*(-1): num2->decimal;
#ifdef DEBUG
   printf("DECIMAL 2: %ld ", dec2);
#endif
   total = dec1 - dec2;
   /*printf("%ld %ld ", total, total*(-1));*/
   totalBin = total>0 ? conDecToBin(total): conDecToBin(total*(-1));
   /*total>0 ? printf("LEFT "): printf("RIGHT");*/
   /*
       if(total>0)
       totalHex = conDecToHex(total);
       else
       totalHex = conDecToHex(total*(-1));
       */
   totalHex = total>0 ? conDecToHex(total): conDecToHex(total*(-1));
   totalOct = total>0 ? conDecToOct(total): conDecToOct(total*(-1));

   /*   totalHex = total>0 ? conDecToHex(total): conDecToHex(total*(-1));*/
   /*printf("%s ", conDecToHex(total));*/
   printf(" ************************ THE DIFFERENCE OF %s", num1->original);
   printf(" AND %s ", num2->original);
   total>0 ? printf("IS: BINARY: %s ", totalBin): printf("IS: BINARY: (-)%s ", totalBin);
   printf("DECIMAL: %li ", total);
   total>0 ? printf("HEXADECIMAL: %s ", totalHex): printf("HEXADECIMAL: (-)%s ", totalHex);
   total>0 ? printf("OCTAL:%s ************************ ", totalOct): printf("OCTAL: (-)%s ************************ ", totalOct);
#ifdef DEBUG
   printf("OUT SUBTRACT ");
#endif
}

/*Multiply the numbers*/
void mult(char* number1, char* number2, char* outbase){
   struct number *num1 = parseNum(number1);
   struct number *num2 = parseNum(number2);
   signed long int total=0, dec1, dec2;
   char * totalBin;
   char * totalHex;
   char * totalOct;
#ifdef DEBUG
   printf("IN MULTIPLY ");
#endif
   dec1 = num1->negative == true ? num1->decimal*(-1): num1->decimal;
#ifdef DEBUG
   printf("DECIMAL 1: %ld ", dec1);
#endif
   dec2 = num2->negative == true ? num2->decimal*(-1): num2->decimal;
#ifdef DEBUG
   printf("DECIMAL 2: %ld ", dec2);
#endif
   total = dec1 * dec2;
   /*printf("%ld %ld ", total, total*(-1));*/
   totalBin = total>0 ? conDecToBin(total): conDecToBin(total*(-1));
   /*total>0 ? printf("LEFT "): printf("RIGHT");*/
   /*
       if(total>0)
       totalHex = conDecToHex(total);
       else
       totalHex = conDecToHex(total*(-1));
       */
   totalHex = total>0 ? conDecToHex(total): conDecToHex(total*(-1));
   totalOct = total>0 ? conDecToOct(total): conDecToOct(total*(-1));

   /*   totalHex = total>0 ? conDecToHex(total): conDecToHex(total*(-1));*/
   /*printf("%s ", conDecToHex(total));*/
   printf(" ************************ THE PRODUCT OF %s", num1->original);
   printf(" AND %s ", num2->original);
   total>0 ? printf("IS: BINARY: %s ", totalBin): printf("IS: BINARY: (-)%s ", totalBin);
   printf("DECIMAL: %li ", total);
   total>0 ? printf("HEXADECIMAL: %s ", totalHex): printf("HEXADECIMAL: (-)%s ", totalHex);
   total>0 ? printf("OCTAL:%s ************************ ", totalOct): printf("OCTAL: (-)%s ************************ ", totalOct);
#ifdef DEBUG
   printf("OUT MULTIPLY ");
#endif

}

struct number * parseNum(char* number){
   struct number *num;
   signed long dec;
   char type;
#ifdef DEBUG
   printf("IN PARSE NUM ");
   printf("TYPE: %c", number[0]);
#endif
   num = (struct number *)malloc(sizeof(struct number));
   /*if number is negative*/
   if(number[0]== '-'){
       num->negative = true;
       type = number[1];
       number = removeFirst(number);
       number = removeFirst(number);
       if(type == 'b'){
           num->binary = number;
           dec = conBinToDec(number);
       }else if(type == 'o'){
           num->oct = number;
           dec = conOctToDec(number);
       }else if(type == 'x'){
           num->hex = number;
           dec = conHexToDec(number);
       }else{
           dec = atol(number);
       }
       /*printf("%s ", number);*/
       num->decimal = dec;
   }else{
       num->negative = false;
       type = number[0];
       number = removeFirst(number);
       if(type == 'b'){
           num->binary = number;
           dec = conBinToDec(number);
       }else if(type == 'o'){
           num->oct = number;
           dec = conOctToDec(number);
       }else if(type == 'x'){
           num->hex = number;
           dec = conHexToDec(number);
       }else{
           dec = atol(number);
       }
       /*printf("%s ", number);*/
       num->decimal = dec;
   }
   num->original = number;
#ifdef DEBUG
   printf("OUT PARSENUM ");
#endif
   return num;
}

/*removes first character in string*/
char *removeFirst(char *charBuffer) {
   char *str;
#ifdef DEBUG
   printf("IN REMOVE FIRST ");
#endif
   if (strlen(charBuffer) == 0)
       str = charBuffer;
   else
       str = charBuffer + 1;
#ifdef DEBUG
   printf("OUT REMOVE FIRST ");
#endif
   return str;
}

/*reverses string*/
char* reverseString(char *str)
{
   char temp;
   size_t len = strlen(str) - 1;
   size_t i;
   size_t k = len;

   for(i = 0; i < len; i++)
   {
       temp = str[k];
       str[k] = str[i];
       str[i] = temp;
       k--;

       /* As 2 characters are changing place for each cycle of the loop
           only traverse half the array of characters */
       if(k == (len / 2))
       {
           break;
       }
   }
   return str;
}

signed long conBinToDec(char* binary){
   struct node * binaryList = (struct node *)malloc(sizeof(struct node));
   struct node * ptr;
   long total=0, i=0;
#ifdef DEBUG
   printf("IN BIN2DEC ");
#endif
   binaryList = binList(binary);
   ptr=binaryList;
   while(ptr!=NULL){
       /*/printf("TOTAL %ld ", total);*/
       /*/printf("ptr->val %d ", ptr->val);*/
       if(ptr->val == 1){
           total += 1<<i;
       }
       i++;
       ptr=ptr->next;

   }
   /*printf(" TOTAL%d ", total);*/
#ifdef DEBUG
   printf("OUT BIN2DEC ");
#endif
   return total;
}

signed long conHexToDec(char* hex){
   int len = strlen (hex), i ;
   signed long total;
   char * string = (char *)malloc((len)*4+1), bin[5];
#ifdef DEBUG
   printf("IN HEX2DEC ");
#endif
   for(i =0; i < len; i++) {
       switch (hex[i]){
           case '0':   strcpy(bin, "0000"); break;
           case '1':   strcpy(bin, "0001"); break;
           case '2':   strcpy(bin, "0010"); break;
           case '3':   strcpy(bin, "0011"); break;
           case '4':   strcpy(bin, "0100"); break;
           case '5':   strcpy(bin, "0101"); break;
           case '6':   strcpy(bin, "0110"); break;
           case '7':   strcpy(bin, "0111"); break;
           case '8':   strcpy(bin, "1000"); break;
           case '9':   strcpy(bin, "1001"); break;
           case 'A':   strcpy(bin, "1010"); break;
           case 'B':   strcpy(bin, "1011"); break;
           case 'C':   strcpy(bin, "1100"); break;
           case 'D':   strcpy(bin, "1101"); break;
           case 'E':   strcpy(bin, "1110"); break;
           case 'F':   strcpy(bin, "1111"); break;
           default:    printf("INVALID CHARACTER"); exit(EXIT_FAILURE);
       }
       strcat(string, bin);
      
   }
   /*printf(" %s in decimal is %ld ",hex, conBinToDec(string));*/
   total =conBinToDec(string);
#ifdef DEBUG
   printf("OUT HEX2DEC ");
#endif
   return total;
}

signed long conOctToDec(char* oct){
   int len = strlen (oct), i ;
   signed long total;
   char * string = (char *)malloc((len)*3+1), bin[4];
#ifdef DEBUG
   printf("IN OCT2DEC ");
#endif
   for(i =0; i < len; i++) {
       switch (oct[i]){
           case '0':   strcpy(bin, "000"); break;
           case '1':   strcpy(bin, "001"); break;
           case '2':   strcpy(bin, "010"); break;
           case '3':   strcpy(bin, "011"); break;
           case '4':   strcpy(bin, "100"); break;
           case '5':   strcpy(bin, "101"); break;
           case '6':   strcpy(bin, "110"); break;
           case '7':   strcpy(bin, "111"); break;
           default:    printf("INVALID CHARACTER"); exit(EXIT_FAILURE);
       }
       strcat(string, bin);
       string[strlen(string)] = '';
       /*printf("THE STRING : %s ", string);*/

   }
   /*printf(" %s in decimal is %ld ",oct, conBinToDec(string));*/
   total =conBinToDec(string);
#ifdef DEBUG
   printf("OUT OCT2DEC ");
#endif
   return total;

}


char * conDecToBin(signed long dec){
   signed long total;
   int i=0;
   char * bin;
#ifdef DEBUG
   printf("IN DEC2BIN ");
#endif
   if(dec == 0){
       return "0";
   }
   total=1;
   while(total<=dec){
       total <<=1;
       i++;
   }
   i--;
   bin= (char *)malloc(i+2);
   bin[i+1]='';
   while(i>=0){
       if(dec%2 == 0)
           bin[i] = '0';
       else if(dec%2 == 1)
           bin[i] = '1';
       dec/=2;
       i--;
   }
#ifdef DEBUG
   printf("OUT DEC2BIN ");
#endif
   return bin;

}

char * conDecToHex(signed long dec){
   int i=0;
   char * binary= conDecToBin(dec), bin[5];
   char * string = (char *)malloc((strlen(binary)+1)/4);
   struct node * binaryList = (struct node *)malloc(sizeof(struct node));
   struct node * ptr;
#ifdef DEBUG
   printf("IN DEC2HEX ");
#endif
   binaryList = binList(binary);
   ptr=binaryList;
   while(ptr!=NULL){
       for(i=0;i<4;i++){
           bin[i] = '';
       }

       for(i=0;i<4;i++){
           if(ptr==NULL)
               break;
           bin[i] = ptr->val == 1 ? '1' : '0';
           ptr=ptr->next;
       }
       for(i=0;i<4;i++){
           if(bin[i] == '')
               bin[i] = '0';
       }

       bin[4] = '';
       if(!strcmp("0000", bin)){   strcat(string, "0");}
       if(!strcmp("0001", bin)){   strcat(string, "8");}
       if(!strcmp("0010", bin)){   strcat(string, "4");}
       if(!strcmp("0011", bin)){   strcat(string, "C");}
       if(!strcmp("0100", bin)){   strcat(string, "2");}
       if(!strcmp("0101", bin)){   strcat(string, "A");}
       if(!strcmp("0110", bin)){   strcat(string, "6");}
       if(!strcmp("0111", bin)){   strcat(string, "E");}
       if(!strcmp("1000", bin)){   strcat(string, "1");}
       if(!strcmp("1001", bin)){   strcat(string, "9");}
       if(!strcmp("1010", bin)){   strcat(string, "5");}
       if(!strcmp("1011", bin)){   strcat(string, "D");}
       if(!strcmp("1100", bin)){   strcat(string, "3");}
       if(!strcmp("1101", bin)){   strcat(string, "B");}
       if(!strcmp("1110", bin)){   strcat(string, "7");}
       if(!strcmp("1111", bin)){   strcat(string, "F");}

       /*printf("Decimal to Binary 4 Digits is: %s and the whole is: %s and hex is : %s ", bin, binary, string);*/
   }
#ifdef DEBUG
   printf("OUT DEC2HEX ");
#endif
   reverseString(string);
   return string;

}

char * conDecToOct(signed long dec){
   int i=0;
   char * binary= conDecToBin(dec), bin[4];
   char * string = (char *)malloc((strlen(binary)+1)/3);
   struct node * binaryList = (struct node *)malloc(sizeof(struct node));
   struct node * ptr;
#ifdef DEBUG
   printf("IN DEC2OCT ");
#endif
   binaryList = binList(binary);
   ptr=binaryList;
   while(ptr!=NULL){
       for(i=0;i<3;i++){
           bin[i] = '';
       }

       for(i=0;i<3;i++){
           if(ptr==NULL)
               break;
           bin[i] = ptr->val == 1 ? '1' : '0';
           ptr=ptr->next;
       }
       for(i=0;i<3;i++){
           if(bin[i] == '')
               bin[i] = '0';
       }

       bin[3] = '';
       if(!strcmp("000", bin)){   strcat(string, "0");}
       if(!strcmp("001", bin)){   strcat(string, "4");}
       if(!strcmp("010", bin)){   strcat(string, "2");}
       if(!strcmp("011", bin)){   strcat(string, "6");}
       if(!strcmp("100", bin)){   strcat(string, "1");}
       if(!strcmp("101", bin)){   strcat(string, "5");}
       if(!strcmp("110", bin)){   strcat(string, "3");}
       if(!strcmp("111", bin)){   strcat(string, "7");}

       /*printf("Decimal to Binary 4 Digits is: %s and the whole is: %s and hex is : %s ", bin, binary, string);*/
   }
#ifdef DEBUG
   printf("OUT DEC2OCT ");
#endif

   return reverseString(string);

}

struct node * binList(char * binary){
   struct node * front = (struct node *)malloc(sizeof(struct node));
   int len, i;
   struct node * newNode;
   struct node * ptr;
#ifdef DEBUG
   printf("IN BINLIST ");
#endif
   front->val=binary[0] - '0';
   /*printf("%d ", front->val);*/
   len = strlen (binary);
   for(i =1; i < len; i++) {
       newNode = (struct node *)malloc(sizeof(struct node));
       newNode->val =binary[i] - '0';
       newNode->next = front;
       front = newNode;
       /*       printf("%d ", newNode->val);*/
   }
   ptr=front;
   i=0;
  
#ifdef DEBUG
   printf("OUT BINLIST ");
#endif
   return front;

}

calc.h

#ifndef CALC_H
#define CALC_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
#include <math.h>

struct number{
   char* binary;
   char* hex;
   char* oct;
   signed long decimal;
   bool negative;
   char* original;
};

struct node{
   int val;
   struct node *next;
};

typedef struct number wholeNum;
typedef signed long int lu;

/*Displays Help Function*/
void help(char* error);
/*Check the arguments*/
void checkArgs(char* arg1, char* arg2, char* arg3, char* arg4);
/*Checks valid binary number*/
void checkBin(char* binary);
/*Checks valid decimal number*/
void checkDec(char* decimal);
/*Checks valid hexadecimal number*/
void checkHex(char* hex);
/*Checks valid Octal number*/
void checkOct(char* oct);

/*Parses string to int*/
struct number * parseNum(char* number);
/*Removes First character of String*/
char* removeFirst(char *charBuffer);
/*Reverses String*/
char* reverseString(char *str);


/*Add the arguments*/
void add(char* number1, char* number2, char* outbase);
/*Substract the arguments*/
void subs(char* number1, char* number2, char* outbase);
/*Multiply the arguments*/
void mult(char* number1, char* number2, char* outbase);

/*Converts Binary to Decimal*/
signed long conBinToDec(char* binary);
/*Converts Decimal to Binary*/
char* conDecToBin(signed long dec);
/*Converts Hexadecimal to Decimal*/
signed long conHexToDec(char* hex);
/*Converts Decimal to Binary*/
char* conDecToHex(signed long dec);
/*Converts Octal to Decimal*/
signed long conOctToDec(char* oct);
/*Converts Decimal to Binary*/
char* conDecToOct(signed long dec);

/*Adds to front of list given a linked list*/
struct number * addFront(char c, struct number * front);
/*Creates linked list of binary numbers in string format*/
struct node * binList(char * binary);
#endif


format.c


#include "format.h"

/* minimum required number of parameters */
#define MIN_REQUIRED 3

/* display usage */
void help(char* error) {
   printf("%s ", error);
   printf("Usage: ./format <OPTIONS> <OPTIONS> [-h] help [argument] <input bit sequence> <type> ");
   exit(EXIT_FAILURE);
   return;
}

int main ( int argc, char **argv ) {
   double time_spent;
   clock_t tic=clock(), toc;
#ifdef DEBUG
   printf("IN MAIN ");
#endif
   /*Displays Help Command*/

   if(argc!=MIN_REQUIRED) {   help("WRONG NUMBER OF ARGUMENTS");}
   if(!strcmp(argv[1], "-h")){   help("HELP: ");}

   if(argc== MIN_REQUIRED){   checkArgs(argv[1], argv[2] );}

   format(argv[1], argv[2]);
   toc = clock();
   time_spent=(double)(toc-tic)/CLOCKS_PER_SEC;
   time_spent=time_spent/1000000;
#ifdef DEBUG
   printf(" ========= TIME SPENT: %.032f ========= ", time_spent);
#endif
#ifdef DEBUG
   printf("OUT OF MAIN ");
#endif
   return 0;
}

/*checks arguments for validity*/
void checkArgs(char* arg1, char* arg2){
   int i;
#ifdef DEBUG
   printf("IN ARG CHECK ");
#endif
   if(strlen(arg1) != 32){
       help("THERE MUST BE 32 BITS");
   }
   for(i=0; i<strlen(arg1); i++){
       if(arg1[i] != '1' && arg1[i] != '0')
           help("INVALID BINARY NUMBER");
   }
   if(strcmp(arg2, "int")!=0){
       if(strcmp(arg2, "float")!=0){
           help("INVALID FORMAT");
       }
   }


#ifdef DEBUG
   printf("OUTARG CHECK ");
#endif
   return;
}


char *removeFirst(char *charBuffer) {
   char *str;
#ifdef DEBUG
   printf("IN REMOVE FIRST ");
#endif
   if (strlen(charBuffer) == 0)
       str = charBuffer;
   else
       str = charBuffer + 1;
#ifdef DEBUG
   printf("OUT REMOVE FIRST ");
#endif
   return str;
}
char* reverseString(char *str)
{
   char temp;
   size_t len = strlen(str) - 1;
   size_t i;
   size_t k = len;

   for(i = 0; i < len; i++)
   {
       temp = str[k];
       str[k] = str[i];
       str[i] = temp;
       k--;

       /* As 2 characters are changing place for each cycle of the loop
           only traverse half the array of characters */
       if(k == (len / 2))
       {
           break;
       }
   }
   return str;
}

void format(char* binary, char* type){
   struct number * ieee = (struct number *)malloc(sizeof(struct number));
   signed long decimal;
   char* sigDecimal;
   int i;
   bool infinity = true;
   bool nan = true;
   ieee->sign = binary[0] == '1'? 1: 0;
   ieee->negative = binary[0] == '1' ? true: false;
   for(i=1; i<9; i++){
       if(binary[i] == '0'){
           infinity = false;
           nan = false;
           break;
       }
   }
   for(i=9; i<33; i++){
       if(binary[i] == '1'){
           infinity = false;
           break;
       }
   }
   if(nan == true){
       for(i=9; i<33; i++){
           if(binary[i] == '1'){
               nan = true;
               break;
           }else{
               nan=false;
           }
       }

   }
   if(nan == true){
       printf("NaN");
       exit(EXIT_SUCCESS);
   }
   if(infinity == true){
       if(ieee->negative == false)
           printf("pinf");
       else
           printf("ninf");
       exit(EXIT_SUCCESS);
   }

   if(!strcmp(type, "int") && ieee->negative == false){
       decimal = conBinToDec(removeFirst(binary));
       printf("INTEGER: %ld ", decimal);
   }
   if(!strcmp(type, "int") && ieee->negative == true){
       decimal = conBinToDec(twoComp(removeFirst(binary)));
       printf("INTEGER: %ld ", (-1)*decimal);
   }
   if(!strcmp(type, "float") && ieee->negative == false){
       sigDecimal = floatParse(removeFirst(binary));
       printf("FLOAT: %s ", sigDecimal);
   }
   if(!strcmp(type, "float") && ieee->negative == true){
       /*printf("TWOS COMPLEMENT: %s ", twoComp(binary));*/
       sigDecimal = floatParse(removeFirst(twoComp(binary)));
       printf("FLOAT:-%s ", sigDecimal);
   }
}

char* twoComp(char* str){
   char* temp = (char*)malloc(strlen(str)+1);
   int i, len=strlen(str);
   bool test=true;
   strcpy(temp, str);
   temp = reverseString(temp);
   /*printf("ORIGINAL STRING: %s REVERSED STRING: %s", str, temp);*/
   for(i = 0; i<len; i++){
       if(test == false){
           temp[i] = temp[i] =='1' ? '0': '1';
       }
       if(temp[i] == '1' && test==true){
           test = false;
       }


   }
   temp = reverseString(temp);
   /*printf("Flipped Bit %s ", temp);*/
   return temp;
}

char* floatParse(char* number){
   char* tempNum = (char*) malloc(strlen(number)+1);
   char* exponent = (char*)malloc(sizeof(char)*9);
   char* mantissa = (char*)malloc(sizeof(char)*24);
   char* final;
   int i, j=0;
   signed long numExponent;
   float numMantissa, total, expo = 1;
   bool zero = true;
   /*printf("NUMBER T0 PARSE %s", number);*/
   for(i=0; i<strlen(number); i++){
       if(number[i] == '1'){
           zero = false;
       }
   }
   if(zero==true){
       return "0.0e0";
   }
   strcpy(tempNum, number);
   for(i=0; i<8; i++){
       exponent[i] = number[i];
   }
   for(i=8; i<32; i++){
       mantissa[j] = number[i];
       j++;
   }
   exponent[8] = '';
   numExponent = conBinToDec(exponent)-127;
   numMantissa = conBinToDec0(mantissa);
   /*printf("EXPONENT: %ld MANTISSA %f ",numExponent, numMantissa);*/
   if(numExponent <0){
       for(i=0; i<-1*numExponent; i++){
           expo /= 2;
           /*printf("%f ",expo );*/

       }
   }
   if(numExponent>0)
       total = numMantissa * (1<<numExponent);
   else
       total = numMantissa * expo;


   final = sigFig(total);
   /*printf("TOTAL : %f ", total);*/
   return final;
}

char* sigFig(float total){
   int exponent=0;
   char* output;
   /*printf("TOTAL %f ", total);*/
   if(total == 0){
       exponent = 0;
       total = 0;
   }
   else if(total >= 1){
       while(total > 10){
           total /= 10;
           exponent++;
       }
   }
   else if(total < 1 && total >0){
       while(total <1){
           total *= 10;
           exponent--;
       }
   }
   output=(char*)malloc(sizeof(char)*33);
   sprintf(output, "%fe%d ", total, exponent);
   return output;
}

float conBinToDec0(char* binary){
   int i;
   float total=0;
   float temp = .5;
#ifdef DEBUG
   printf("IN BIN TO DEC <0 ");
#endif
   /*printf("TOTAL: %f TEMP: %f ", total, temp);*/
   for(i=0; i<strlen(binary); i++){
       if(binary[i] == '1'){
           total +=temp;
       }
       temp /=2;
       /*printf("TOTAL: %.6f TEMP: %.6f ", total, temp);*/
   }
   /*printf("TOTAL FLOAT: %f ", total);*/
#ifdef DEBUG
   printf("OUT BIN TO DEC <0 ");
#endif
   return (total+1);
}


signed long conBinToDec(char* binary){
   struct node * binaryList = (struct node *)malloc(sizeof(struct node));
   struct node * ptr;
   long total=0, i=0;
#ifdef DEBUG
   printf("IN BIN2DEC ");
#endif
   binaryList = binList(binary);
   ptr=binaryList;
   while(ptr!=NULL){
       /*/printf("TOTAL %ld ", total);*/
       /*/printf("ptr->val %d ", ptr->val);*/
       if(ptr->val == 1){
           total += 1<<i;
       }
       i++;
       ptr=ptr->next;

   }
   /*printf(" TOTAL%d ", total);*/
#ifdef DEBUG
   printf("OUT BIN2DEC ");
#endif
   return total;
}


char * conDecToBin(signed long dec){
   signed long total;
   int i=0;
   char * bin;
#ifdef DEBUG
   printf("IN DEC2BIN ");
#endif
   if(dec == 0){
       return "0";
   }
   total=1;
   while(total<=dec){
       total <<=1;
       i++;
   }
   i--;
   bin= (char *)malloc(i+2);
   bin[i+1]='';
#ifdef DEBUG
   printf("%lu %lu %d %s ", dec, total, i, bin);
#endif
   while(i>=0){
       if(dec%2 == 0)
           bin[i] = '0';
       else if(dec%2 == 1)
           bin[i] = '1';
       dec/=2;
       i--;
   }
#ifdef DEBUG
   printf("%ld %ld %d %s ", dec, total, i, bin);
#endif
#ifdef DEBUG
   printf("OUT DEC2BIN ");
#endif
   return bin;

}

struct node * binList(char * binary){
   struct node * front = (struct node *)malloc(sizeof(struct node));
   int len, i;
   struct node * newNode;
   struct node * ptr;
#ifdef DEBUG
   printf("IN BINLIST ");
#endif
   front->val=binary[0] - '0';
   /*printf("%d ", front->val);*/
   len = strlen (binary);
   for(i =1; i < len; i++) {
       newNode = (struct node *)malloc(sizeof(struct node));
       newNode->val =binary[i] - '0';
       newNode->next = front;
       front = newNode;
       /*       printf("%d ", newNode->val);*/
   }
   ptr=front;
   i=0;
   /*printf("BINARY REVERSE FOR %s is ", binary);*/
   while(ptr!=NULL){
       /*printf("%d", ptr->val);*/
       ptr=ptr->next;
   }
   printf(" ");
#ifdef DEBUG
   printf("OUT BINLIST ");
#endif
   return front;
}

format.h

#ifndef FORMAT_H
#define FORMAT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
#include <math.h>

struct number{
   int sign;

   char* exponent;
   char* mantissa;
   bool negative;
   char* original;
   signed long decimal;
};

struct node{
   int val;
   struct node *next;
};

typedef struct number wholeNum;
typedef signed long int lu;

/*Displays Help Function*/
void help(char* error);
/*Check the arguments*/
void checkArgs(char* arg1, char* arg2);
/*Checks valid binary number*/
void checkBin(char* binary);
/*Checks valid decimal number*/
void checkDe(char* binary);
/*Checks valid hexadecimal number*/
void checkHex(char* binary);
/*Checks valid Octal number*/
void checkOct(char* binary);

/*formats 32 bit sequence*/
void format(char* binary, char* type);
/*Removes First character of String*/
char *removeFirst(char *charBuffer);
/*Reverses String*/
char* reverseString(char *str);
/*twos complement*/
char* twoComp(char* str);
/*Parses IEEE 754 to float*/
char* floatParse(char* number);
/*Converts total to Scientific notation*/
char* sigFig(float total);

/*Converts Binary to Decimal Lower than 0*/
float conBinToDec0(char* binary);
/*Converts Binary to Decimal*/
signed long conBinToDec(char* binary);
/*Converts Decimal to Binary*/
char * conDecToBin(signed long dec);

/*Adds to front of list given a linked list*/
struct number * addFront(char c, struct number * front);
/*Creates linked list of binary numbers in string format*/
struct node * binList(char * binary);
#endif