/***********************/
Processor : MCF5485
IDE: CW-6.4 Build 6
/***********************/
Hi all,
I need a sprintf in my code to convert a float to string...
In my product there is an external interrupt every 6ms....
CASE1:
/***************************************************/
debugVarFloat - Array
sprintf
debugVarString - Array
/***************************************************/
In the above code if I observe the debugVar contents, I can see that the input is OK. But the output is corrupted sometimes....randomly.
CASE2:
/***************************************************/
debugVarFloat - Array
DISABLE_INTERRUPTS
sprintf
ENABLE_INTERRUPTS
debugVarString - Array
/***************************************************/
In this case, both the input and output are OK. But execution of sprintf takes 10ms on my platform. So my board will not be able to respond to an external interrupt. THis is fatal to our system.
I tried to use the following alternatives:
1. vsnprintf - It took almost the same time as sprintf....
2. stringstreams - The same behavior was repeated...
Is there a faster way to convert a float to string?
Is there any way that I could make sprintf, corruption proof??
Please guide me through this...
Thanks and Regards,
Venki
Solved! Go to Solution.
Hi Kef,
Thanks a lot...
I done the modification you suggested...It works fine.
Also I had a bug in my prev code....
It could not distinguish between 0.00X and 0.X/0.0X.
I have made suitable modifications, for this bug....
void convFloatStr(double floatVar, char* floatStr) { int intPart=0; int intLen=0; double fractional; char charArr[20] = {0}; char nullArr[20] = {0}; int decimalPoint=0; int tempInt=0; int i=0; if(floatVar >0) floatVar = floatVar + 0.000005; else floatVar = floatVar - 0.000005; intPart = (int)floatVar; itoa(intPart, floatStr, 10); intLen = strlen(floatStr); strcat(floatStr, "."); if(intLen < 5) fractional = floatVar * 100000; else fractional = floatVar * 1000; itoa(fractional, charArr, 10); if(floatStr[0] != '0') strcat(floatStr, &charArr[intLen]); else { while(1) { tempInt = (int)(floatVar) * 10 / 1 ; floatVar = ((floatVar) * 10 ); decimalPoint++; if(tempInt) break; } decimalPoint = decimalPoint - 2; for(i=0;i<decimalPoint ;i++) strcat(floatStr, "0"); strcat(floatStr, charArr); } }
This code takes around 250 micro seconds on my board. A lot faster than the sprintf(10-11 milliseconds). The application works fine, without any data corruption. Thanks to all for your support.
You may need to roll your own floating-point to string conversion routine, to reduce both the time required to forma the output and reduce the memory footprint. If you're talking about converting straight binary data, I think some code has been posted in the forums to do this. For floating-point, you might want to scout around on Google.
---Tom
Hi,
Thanks for the guidance, I have rolled out a small piece of code, which will serve my purpose...
I'm posting the code below:
void convFloatStr(double floatVar, char* floatStr){int intPart=0;int intLen=0; double fractional;char charArr[20]= {0}; intPart = (int)floatVar;itoa(intPart, floatStr, 10);intLen = strlen(floatStr);strcat(floatStr, ".");if(intLen < 5) fractional = floatVar * 100000;else fractional = floatVar * 1000;ltoa(fractional, charArr, 10);if(floatStr[0] != '0') strcat(floatStr, &charArr[intLen]);else strcat(floatStr, charArr); }
Please let me know if any improvements can be made to the code.
As of now the known bugs are:
#1
If I input 2.9...o/p is 2.29999
But the same is not happening with 3.9, 4.9 or 5.9.....
#2
Input : 9.7
Output : 9.69999
This strange behavior is only for a few combnation of numbers!!!!
Any suggestions on this????
This is not a strange behaviour. For example 3.9 and 4.9 can't be represented exactly equal to 3.9/4.9 in binary base floating point number. Closest to 3.9 double is little below 3.9, it's 3.8999999999.. . Closest to 4.9 double is little above 4.9, it's about 4.9000000000000004 . Conversion from FP to integer in C doesn't round to closest number, it just chops the fractional part. So if you want to convert only 5 digits past dot, then you should round your floating number first, by adding 0.000005 for positive numbers, subracting 0.000005 from negative numbers.
Hi Kef,
Thanks a lot...
I done the modification you suggested...It works fine.
Also I had a bug in my prev code....
It could not distinguish between 0.00X and 0.X/0.0X.
I have made suitable modifications, for this bug....
void convFloatStr(double floatVar, char* floatStr) { int intPart=0; int intLen=0; double fractional; char charArr[20] = {0}; char nullArr[20] = {0}; int decimalPoint=0; int tempInt=0; int i=0; if(floatVar >0) floatVar = floatVar + 0.000005; else floatVar = floatVar - 0.000005; intPart = (int)floatVar; itoa(intPart, floatStr, 10); intLen = strlen(floatStr); strcat(floatStr, "."); if(intLen < 5) fractional = floatVar * 100000; else fractional = floatVar * 1000; itoa(fractional, charArr, 10); if(floatStr[0] != '0') strcat(floatStr, &charArr[intLen]); else { while(1) { tempInt = (int)(floatVar) * 10 / 1 ; floatVar = ((floatVar) * 10 ); decimalPoint++; if(tempInt) break; } decimalPoint = decimalPoint - 2; for(i=0;i<decimalPoint ;i++) strcat(floatStr, "0"); strcat(floatStr, charArr); } }
This code takes around 250 micro seconds on my board. A lot faster than the sprintf(10-11 milliseconds). The application works fine, without any data corruption. Thanks to all for your support.