Write these programs in C ONLY This assignment is designed to help you learn the
ID: 3854640 • 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 examplesExplanation / 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;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.