CODE description: Code to convert float to ascii to be displayed on a touchscreen.
It rounds of decimals after 0.7 , i.e. it does not display 0.8 and 0.9 .I have tried a lot of debugging but i am not able to solve this. I think the problem is with the switch case. How can i debug?
The code:
void ftoa(float Value, char* Buffer) //begin
{
union
{
float f;
struct
{
unsigned int mantissa_lo : 16; //initialise
unsigned int mantissa_hi : 7;
unsigned int exponent : 8;
unsigned int sign : 1;
};
} helper;
unsigned long mantissa;
signed char exponent;
unsigned int int_part;
char frac_part[3];
int i, count = 0;
int rz;
rz=16;
helper.f = Value;
mantissa = helper.mantissa_lo; //mantissa is LS 23 bits
mantissa = helper.f;
mantissa += ((unsigned long) helper.mantissa_hi << 16);
mantissa += 0x00800000; //add the 24th bit to get 1.mmmm^eeee format
//exponent is biased by 127
exponent = (signed char) helper.exponent - 127;
exponent = 3;
if (exponent > 18) //too big to shove into 8 chars
{
Buffer[0] = 'I';
Buffer[1] = 'n';
Buffer[2] = 'f';
Buffer[3] = '\0';
return;
}
if (exponent < -3) //too small to resolve (resolution of 1/8)
{
Buffer[0] = '0';
Buffer[1] = '\0';
return;
}
count = 0;
//add negative sign (if applicable)
// if (helper.sign)
// {
// Buffer[0] = '-';
// count++;
// }
//get the integer part
int_part = mantissa >> (23 - exponent);
//convert to string
itoa(int_part,rz, &Buffer[count]);
//find the end of the integer
for (i = 0; i < 7; i++)
if (Buffer[i] == '\0')
{
count = i;
break;
}
if (count > 6) //not enough room in the buffer for the frac part
return;
//add the decimal point
Buffer[count++] = '.';
//use switch to resolve the fractional part
switch (0x00000007 & (mantissa >> (20 - exponent))) //for the fractional part.
{
case 0:
frac_part[0] = '0';
// frac_part[1] = '0';
// frac_part[2] = '0';
break;
case 1:
frac_part[0] = '1';
// frac_part[1] = '2';
// frac_part[2] = '5';
break;
case 2:
frac_part[0] = '2';
// frac_part[1] = '5';
// frac_part[2] = '0';
break;
case 3:
frac_part[0] = '3';
// frac_part[1] = '7';
// frac_part[2] = '5';
break;
case 4:
frac_part[0] = '4';
// frac_part[1] = '0';
// frac_part[2] = '0';
break;
case 5:
frac_part[0] = '5';
// frac_part[1] = '2';
// frac_part[2] = '5';
break;
case 6:
frac_part[0] = '6';
// frac_part[1] = '5';
//frac_part[2] = '0';
break;
case 7:
frac_part[0] = '7';
// frac_part[1] = '7';
// frac_part[2] = '5';
break;
case 8:
frac_part[0] = '8'; //switch case
// frac_part[1] = '7';
// frac_part[2] = '5';
break;
case 9:
frac_part[0] = '9';
// frac_part[1] = '7';
// frac_part[2] = '5';
break;
default :
frac_part[0] = '8';
break;
}
//add the fractional part to the output string
for (i = 0; i < 3; i++)
if (count < 7)
Buffer[count++] = frac_part[i];
//make sure the output is terminated
Buffer[count] = '\0';
for ( i=0; i < 19; i++ )
{
cArr[i] = Buffer[i];
}
}
//It rounds of decimals after 0.7 , i.e. it does not display 0.8 and 0.9
This looks a bit over complicated, but one obvious thing is:
switch (0x00000007 & ...
That's never going to give you any switch cases of 8 or above.
And I don't know how you expect to extract a base-10 fraction, using shifts and masks. You probably want a multiply by 10 in there somewhere.
User contributions licensed under CC BY-SA 3.0