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: 3854713 • 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 <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

int checkOperation(char * input){//Check the operation
    if(input[0] == '+'){
        return 1;
    }
    else if(input[0] == '-'){
        return 2;
    }
    else if(input[0] == '*'){
        return 3;
    }
    else{
        return 666;//invalid operation
    }
}

int checkSign(char * input){//Check the sign
    if(input[0] == '-'){
        return 1;
    }
    else{
        return 0; //positive
    }
}

int checkCorrectBase(char x,int base){
    if(((x - '0') < 10) && ((x -'0') < base)){
        return 0;
    }
    else if((base > 10) && (((x - 'A' + 10) < base) || ((x - 'a' + 10) < base))){
        return 0;
    }
    else
        return 1;
}

int checkBase(char * input){ //Check the base
    if(input[0] == '-'){
        if(input[1] == 'b'){
            return 2;
        }
        else if(input[1] == 'd'){
            return 10;
        }
        else if(input[1] == 'o'){
            return 8;
        }
        else if(input [1] == 'x'){
            return 16;
        }
    }
    else if(input[0] == 'b'){
        return 2;
    }
    else if(input[0] == 'd'){
        return 10;
    }
    else if(input[0] == 'o'){
        return 8;
    }
    else if(input [0] == 'x'){
        return 16;
    }
    else{
        return 666;
    }

    return 666;
}
/* //code is no longer used
char * intToBinaryASCII(unsigned int x, char * output){//convert int to ascii
    unsigned int i, n = 0;
    char * cstr = malloc(3);
    output[0] = '';
    for(i = 0; i<32; i++){
        n = x>>31;
        cstr[0] = '0' + n;
        cstr[1] = '';
        strcat(output,cstr);
        x = x<< 1;
    }
    i = 0;
    while(output[i] == '0'){
        i++;
    }
    cstr = 0;
    free(cstr);
   // printf("test1");
    return output + i;
}
unsigned int binASCIIToInt(char * str){
    int i, value = 0;
    for(i = 0; str[i] != ''; i++){
   //   printf("run : %d ", i);
        switch(str[i])
        {
            case '0':
                value = (value<<1);
                //printf("%d ", value);
                break;
            case '1':
                value = (value<<1)+1;
                //printf("%d ", value);
                break;
            default:
                printf("Error: Something went wrong binToASCII");
                return 0;
        }
    }
    //printf("test0");
    return value;
}
*/
char * intToASCII(int x, char * output,int base,int sign){//converts int to ascii
    //char * octChar = "01234567";
    if(sign == 1){
        x = x*-1;
    }
    int i,n = 0;
    char * cstr = malloc(32);
    //char c = 0;
    char * output2 = malloc(32);
    output2[0] = '';
    while(x!=0){
        cstr[0]= (x%base) + '0';
        if(x%base > 9){
            n = base - x%base;
            cstr[0] = 'G' - n;
        }
        cstr[1] = '';
        //printf("-%s- ", cstr);
        strcat(output2,cstr);
        x /= base;  
    }

    i = 0;
    while(i < strlen(output2)){
        output[i] = output2[strlen(output2)-i-1];
        //printf("-%c- ", output[i]);
        i++;
    }

    cstr = 0;
    free(cstr);
  
    return output;
}

int ASCIIToInt(char * str,int base, int sign) {//converts ascii to int

    int output = 0;
    int i = 0;
    while(str[i] != ''){
        if(str[i] >= 'a' && str[i] <= 'f'){
            output = output*base + str[i] - 'a' + 10;
        }
        else if(str[i] >= 'A' && str[i] <= 'F'){
            output = output*base + str[i] - 'A' + 10;
        }
        else
            output = output*base + str[i] - '0';

        i++;
    }

    if(sign == 1){
        output = output *-1;
    }

    return output;
}
/*//No longer used code
unsigned int octASCIIToInt(char * str){
    int i, value = 0;
    for(i = 0; str[i]!= ''; i++){
//        printf("run %d ", i);
        switch(str[i]){
            case '0': value = (value<<3); break;
            case '4': value = (value<<1) + 1;
                      value = (value<<2);
                      break;
            case '2': value = (value<<2) + 1;
                      value = (value<<1);
                      break;
            case '6': value = (value<<1) + 1;
                      value = (value<<1) + 1;
                      value = (value<<1);
                      break;
            case '1': value = (value<<3) + 1;
                      break;
            case '5': value = (value<<1)+1;
                      value = (value<<2)+1;
                      break;
            case '3': value = (value<<2)+1;
                      value = (value<<1)+1;
                      break;
            case '7': value = (value<<1) +1;
                      value = (value<<1) +1;
                      value = (value<<1) +1;
                      break;
            default: printf("not happy %c ", str[i]); return 1;
        }
    }
// printf("value %d ", value);
    return value;
}
*/

int main(int argc, char **argv){

    if(argc != 5){
        fprintf(stderr,"ERROR: Incorrect number of inputs ");
        return 0;
    }

    int operation = 0;
    int sign1 = 0;
    int base1 = 0;
    int sign2 = 0;
    int base2 = 0;
    int value1 = 0;
    int value2 = 0;
    int output = 0;
    int outputSign = 0;
    char baseChar = argv[4][0];
    int base = checkBase(argv[4]);

    if(base == 666){
        fprintf(stderr, "ERROR: Incorrect output type ");
        return 0;
    }

    operation = checkOperation(argv[1]);  
    if(operation == 666){
        fprintf(stderr,"ERROR: Invalid operation '%s' ", argv[1]);
        return 0;
    }
    //printf("%d , %s ", operation, argv[1]);
    sign1 = checkSign(argv[2]);
    base1 = checkBase(argv[2]);
    if(base1 == 666){
        fprintf(stderr,"ERROR: Invalid base '%s' ", argv[2]);
        return 0;
    }

    int i;
    for(i = 1; i < strlen(argv[2]); i++){
        if(checkCorrectBase(argv[2][i],base1)){
            fprintf(stderr, "ERROR: Invalid input ");
            return 0;
        }
    }

    //printf("%d , %s ", sign1, argv[2]);
    //printf("%d , %s ", base1, argv[2]);
  
    sign2 = checkSign(argv[3]);
    base2 = checkBase(argv[3]);
    if(base2 == 666){
        fprintf(stderr,"ERROR: Invalid base '%s' ", argv[3]);
        return 0;
    }
    for(i = 1; i < strlen(argv[3]); i++){
           if(checkCorrectBase(argv[3][i],base2)){
               fprintf(stderr, "ERROR: Invalid input ");
               return 0;
           }
       }


  
    switch(base1){
        case(2):
            value1 = ASCIIToInt(argv[2] + 1 + sign1,base1,sign1);
            //char * output = malloc(strlen(argv[2]));
            //printf("b%s ", intToASCII(value1,output,base1,sign1));
            break;
        case(8):
            //to be filled
            value1 = ASCIIToInt(argv[2] + 1 + sign1,base1,sign1);
            //char * output2 = malloc(strlen(argv[2]));
            //printf("o%s ", intToASCII(value1,output2,base1,sign1));
            break;
        case(10):
            //to be filled
            value1 = ASCIIToInt(argv[2] + 1 + sign1,base1,sign1);
            //char * output3 = malloc(strlen(argv[2]));
            //printf("o%s ", intToASCII(value1,output3,base1,sign1));
            break;
        case(16):
            //to be filled
            value1 = ASCIIToInt(argv[2] + 1 + sign1,base1,sign1);
            //char * output4 = malloc(strlen(argv[2]));
            //printf("o%s ", intToASCII(value1,output4,base1,sign1));
            break;
    }

     switch(base2){
        case(2):
            value2 = ASCIIToInt(argv[3] + 1 + sign2,base2,sign2);
            //char * output = malloc(strlen(argv[2]));
            //printf("b%s ", intToASCII(value2,output,base2,sign2));
            break;
        case(8):
            //to be filled
            value2 = ASCIIToInt(argv[3] + 1 + sign2,base2,sign2);
            //char * output2 = malloc(strlen(argv[2]));
            //printf("o%s ", intToASCII(value1,output2,base1,sign1));
            break;
        case(10):
            //to be filled
            value2 = ASCIIToInt(argv[3] + 1 + sign2,base2,sign2);
            //char * output3 = malloc(strlen(argv[2]));
            //printf("o%s ", intToASCII(value1,output3,base1,sign1));
            break;
        case(16):
            //to be filled
            value2 = ASCIIToInt(argv[3] + 1 + sign2,base2,sign2);
            //char * output4 = malloc(strlen(argv[2]));
            //printf("o%s ", intToASCII(value1,output4,base1,sign1));
            break;
    }

    switch(operation){
        case 1:
            output = value1 + value2;
            if(output < 0){
                outputSign = 1;
            }
            break;
        case 2:
            output = value1 - value2;
            if(output < 0){
                outputSign = 1;
            }
            break;
         case 3:
            output = value1 * value2;
            if(output < 0) {
                outputSign = 1;
            }
            break;
    }


    char * outputStr = malloc(35);
    char signChar = 0;
    if(outputSign == 1){
        signChar = '-';       
    }

    //you can also use strings and concat
    fprintf(stdout,"%c%c%s ", signChar,baseChar,intToASCII(output,outputStr,base,outputSign));

    //printf("%d , %s ", sign2, argv[3]);
    //printf("%d , %s ", base2, argv[3]);
  
    return 0;
}

----------------------------------------------------------------------------------------
format.c
-----------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

char * intToASCII(int x, char * output,int base,int sign){
    //char * octChar = "01234567";
    if(sign == 1){
        x = x*-1;
    }
    int i,n = 0;
    char * cstr = malloc(32);
    //char c = 0;
    char * output2 = malloc(32);
    output2[0] = '';
    while(x!=0){
        cstr[0]= (x%base) + '0';
        if(x%base > 9){
            n = base - x%base;
            cstr[0] = 'G' - n;
        }
        cstr[1] = '';
        //printf("-%s- ", cstr);
        strcat(output2,cstr);
        x /= base;  
    }

    i = 0;
    while(i < strlen(output2)){
        output[i] = output2[strlen(output2)-i-1];
        //printf("-%c- ", output[i]);
        i++;
    }

    cstr = 0;
    free(cstr);
    output2 = 0;
    free(output2);
  
    return output;
}

int ASCIIToInt(char * str,int base, int sign) {

    int output = 0;
    int i = 0;
    while(str[i] != ''){
        if(str[i] >= 'a' && str[i] <= 'f'){
            output = output*base + str[i] - 'a' + 10;
        }
        else if(str[i] >= 'A' && str[i] <= 'F'){
            output = output*base + str[i] - 'A' + 10;
        }
        else
            output = output*base + str[i] - '0';

        i++;
    }

    if(sign == 1){
        output = output *-1;
    }

    return output;
}

static void
get_float_digit( float x, char * digit, int * pow10, float * remainder )
{
   int           p10;

   if ( x == 0.0 )
   {
       *digit = '0';           // digit is always '0'
       *pow10 = 0;
       *remainder = 0.0;
   }
   else
   {
       *pow10 = 0;           // start with 10^0
       while ( x >= 10.0 )       // reduce
       {
           x /= 10.0;       // large values get smaller
           *pow10 += 1;
       }
       while ( x < 1.0 )       // increase
       {
           x *= 10.0;       // small values get larger
           *pow10 -= 1;
       }
       *digit = '0';
       do {               // 10.0 > x >= 1.0
           x -= 1.0;
           *digit += 1;       // digit is always non-'0'zero
       } while ( x >= 1.0 );
       p10 = 0;
       while ( p10 > *pow10 )       // leading digit is now removed from x
       {
           x /= 10;
           p10 -= 1;
       }
       while ( p10 < *pow10 )
       {
           x *= 10;
           p10 += 1;
       }
       *remainder = x;
   }
}

// Improve efficiency by adding more while loops to handle larger powers of 10, e.g. :
// while ( x >= 1e1024 ) { x /= 1e0124; pow10 += 1024; }
// while ( x >= 1e512 ) { x /= 1e512; pow10 += 512; }
// ...
// while ( x >= 10.0 ) { x /= 10.0 ; pow10 += 1; }
// And
// while ( x < 1.0 ) { x *= 10; pow10 -= 1; }
// ...
// while ( x < 1e-512 ) { x *= 1e512; pow10 -= 512; }
// while ( x < 1e-1024 ) { x *= 1e1024; pow10 -= 1024; }

static void
append( char * s, char c )
{
   char       buf[2];

   buf[0] = c;
   buf[1] = '';
   strcat( s, buf );
}

union Number {
   int   i;
   float   f;
};

void
floatToASCII( float x, char * output )
{
   char       c;
   int       pow10, p10, plast;
   int       i;
   float       remainder;
   char       exponent[10];
   union Number   a;
   unsigned int   biasedExp;
   unsigned int   mantissa;
   int       sign;

   a.f = x;
   biasedExp = a.i >> 23 & 0x000000ff;
   mantissa = a.i & 0x007fffff;
   sign = a.i >> 31;
   //printf( "BKR x is %g. biasedExp is %x mantissa is %08x sign is %d ", x,
//       biasedExp, mantissa, sign );
   if ( biasedExp == 0xff )
   {
       if ( mantissa == 0 )
       {
           if ( sign != 0 )
           {
               strcpy( output, "-inf" );
       printf( "BKR returning from file %s line %d ", __FILE__, __LINE__ );
               return;
           }
           else
           {
               strcpy( output, "+inf" );
       printf( "BKR returning from file %s line %d ", __FILE__, __LINE__ );
               return;
           }
       }
       else
       {
           if ( sign != 0 )
           {
               strcpy( output, "-NaN" );
       printf( "BKR returning from file %s line %d ", __FILE__, __LINE__ );
               return;
           }
           else
           {
               strcpy( output, "+NaN" );
       printf( "BKR returning from file %s line %d ", __FILE__, __LINE__ );
               return;
           }
       }
   }
   output[0] ='';
   if ( x < 0.0 )
   {
       append( output, '-' );
       x = -x;                   // make x positive
   }
   get_float_digit( x, &c, &pow10, &remainder );
   append( output, c );
   append( output, '.' );
   x = remainder;
   plast = p10 = pow10;           // pow10 set by get_float_digit()
   for ( i = 1 ; i < 7 ; i++ )       // 7 significant digits in 32-bit float
   {
       get_float_digit( x, &c, &p10, &remainder );
       if ( (plast - p10) > 1 )
       {
           append( output, '0' );   // fill in zero to next nonzero digit
           plast -= 1;
       }
       else
       {
           append( output, c );
           x = remainder;
           plast = p10;
       }
   }
   if ( pow10 < 0 )       // negative exponent
   {
       exponent[0] = 'e';
       intToASCII( pow10, exponent+1,10,1);
   }
   else if ( pow10 < 10 )       // positive single-digit exponent
   {
       exponent[0] = 'e';
   //   exponent[1] = '+';
       exponent[1] = '0';
       intToASCII( pow10, exponent+2,10,0);
   }
   else               // positive multi-digit exponent
   {
       exponent[0] = 'e';
   //   exponent[1] = '+';
       intToASCII( pow10, exponent+1 ,10,0);
   }
   strcat( output, exponent );
}

int main(int argc, char ** argv){
    if(argc != 3){
        fprintf(stderr, "ERROR: Incorrect number of arguments ");
        return 0;
    }
    if(strlen(argv[1]) != 32){
        fprintf(stderr,"ERROR: Input is not a 32 bit size binary number. ");
        return 0;
    }

    int i;
    for(i = 0; i < 32; i++){
        if(argv[1][i] != '1' && argv[1][i] != '0'){
            fprintf(stderr,"ERROR: Binary input contains invalid characters. ");
            //printf("%d ",i);
            return 0;
        }
    }


    if(strcmp(argv[2],"float") == 0){
        char * output = malloc(35);
        //int sign = 0;
        //char signchar = 0;
        int x = ASCIIToInt(argv[1],2,0);
        float y = 0;
        memcpy(&y,&x,sizeof(x));
        /*
        if(x < 0){
            sign = 1;
            signchar = '-';
        }*/
        floatToASCII(y,output);
        //strcat(output," ");//better to include in the formal string
        fprintf(stdout,"%s ",output);
        free(output);
        //printf("%s ",output);
        //printf("%d ", x);


    }
    else if(strcmp(argv[2],"int") == 0){
        char * output = malloc(35);
        int sign = 0;
        char * signchar = malloc(36);
        signchar[0] = 0;
        int x = ASCIIToInt(argv[1],2,0);
        if(x < 0){
            sign = 1;
            signchar[0] = '-';
        }
      

        output = intToASCII(ASCIIToInt(argv[1],2,0),output,10,sign);
        strcat(signchar,output);
        fprintf(stdout,"%s ", signchar);
        free(output);
        free(signchar);
//:      printf("%d ", x);
    }
    else{
        fprintf(stderr,"ERROR: Incorrect output type ");
    }
  

    return 0;
}