Made a program to convert from 32-bit binary to floating point number. When I tr
ID: 3757467 • Letter: M
Question
Made a program to convert from 32-bit binary to floating point number. When I try to use it in the command line it always prints out 52.000 and I have no clue why. Please help.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//Input: get_Int functions takes user input in binary and converts it to an integer
//Input: we loop through the 32 bit value and bit shift it over to the left to get to decimal
//Output: Returns value which is the integer representation of the input binary number
int get_Int(const char *input){
int intNumber = 0;
for(int i = 0; i < 32; ++i){
intNumber = intNumber | ((input[i] == '1') << (31-i));
}
return intNumber;
}
// Convert IEEE 32-bit floating point to printable ASCII string
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;
}
}
static void
append( char * s, char c )
{
char buf[2];
buf[0] = c;
buf[1] = '';
strcat( s, buf );
}
union Number {
int i;
float f;
};
char
floatToASCII( char 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;
if(biasedExp==255){
if(sign==0){
printf("Positive Infinity ");
}
else{
printf("Negative Infinity ");
}
}
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';
// get_Int( &pow10, exponent+1 );
}
else if ( pow10 < 10 ) // positive single-digit exponent
{
exponent[0] = 'e';
exponent[1] = '+';
exponent[2] = '0';
//get_Int( &pow10, exponent+3 );
}
else // positive multi-digit exponent
{
exponent[0] = 'e';
exponent[1] = '+';
//get_Int( &pow10, exponent+2 );
}
strcat( output, exponent );
return *output;
}
int main(int argc, char *argv[]){
float floatMethod = 0;
int intMethod = 0;
if(argc!=3){
fprintf(stderr,"ERROR wrong number of input parameters");
return -1;
}
const char* bits = argv[1];
for(int i = 0; i < 32; ++i){
if((bits[i]!='1') && (bits[i]!='0')){
fprintf(stderr,"ERROR input number conatins non-binary characters");
return -1;
}
}
floatMethod = strcmp(argv[2], "float") == 0;
intMethod =strcmp(argv[2], "int") == 0;
char *output_float = malloc(64);
if(intMethod){
int value = get_Int(argv[1]);
printf("%d", value);
}
else if (floatMethod){
float value = floatToASCII(*argv[1],output_float);
printf("%f",value);
}
else{
return 0;
}
}
Explanation / Answer
The output of function floatToASCII() is not correct. You are retruning only single character of the output and reading it into a float variable in main() in following line:
float value = floatToASCII(*argv[1],output_float);
Change the return type of floatToASCII() to float (from char) in function definition and last line of the function to
return atof(output);
This will convert the string into a floating point number.
Edited function:
float
floatToASCII( char 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;
if(biasedExp==255){
if(sign==0){
printf("Positive Infinity ");
}
else{
printf("Negative Infinity ");
}
}
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';
// get_Int( &pow10, exponent+1 );
}
else if ( pow10 < 10 ) // positive single-digit exponent
{
exponent[0] = 'e';
exponent[1] = '+';
exponent[2] = '0';
//get_Int( &pow10, exponent+3 );
}
else // positive multi-digit exponent
{
exponent[0] = 'e';
exponent[1] = '+';
//get_Int( &pow10, exponent+2 );
}
strcat( output, exponent );
return atof(output);
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.