问题
I'm trying to perform string to double conversion. In gnu c compiler I'm getting correct values. But if I use it in my embedded compiler (renesas CS+) it is giving undefined behavior like returning infinity result.
Here is my code:
double str_to_double_func(char a[])
{
char str[30] = {'0'};
int loop ;
double result;
int len ;
int pos,n;
for(loop = 0;a[loop]!='\0';loop++)
{
str[loop] = a[loop];
}
str[loop] = '\0';
pos = 0;
len = sizeof(str)-1;
for (n = 0; n < len; n++)
{
if (str[n] == '.')
{
pos = len - n - 1;
}
else
{
result = result * 10.0f + (str[n]-'0');
}
}
while ( pos--)
{
result = result/10.0f;
}
return result;
}
void geo_app_main()
{
double d,i;
d = str_to_double_func("12.345678");
}
This same code I'm using in my CS+ compiler (renesas microcontroller) without printf statements. When i run this code in simulator it is returning infinite value (d = infinite value).
Now i changed my code
double str_to_double_func(char str[])
{
double result = 0.0;
int len = 0;
int pos = 0, n;
while(str[len]!='\0'){
len++;
}
for (n = 0; n < len; n++)
{
if (str[n] == '.')
{
pos = len - n - 1;
}
else
{
result = result * 10.0f + (str[n]-'0');
}
}
while ( pos--)
{
result = result/1.0f;
}
return result;
}
Here the problem is getting 1.234567800000000E+001 instead of 12.345678 in my CS+(renesasa micro) compiler.i checked this code with cigwin compiler.There i'm getting correct output.
the simulator output is result=result 1.234567800000000E+001 double(8)R6:REG, R7:REG
回答1:
You must initialise your result. When you define
double result;
it is not guaranteed to be zero. It can have any value and will probably be garbage. Especially if every subsequent operation relies on result having a valid value:
result = result * 10.0f + (str[n]-'0');
...
result = result/10.0f;
You should initialise your variable to
double result = 0.0;
A memory checker such as Valgrind can help you to find operations on uninitialised values.
There's also the issue Sourav Ghosh pointed out: sizeof does not give you then length of a string. You should use strlen from <string.h> for that. But in your case, you don't really need it, because you already determine the length when you copy the string in loop.
And, of, course, you should explicitly initialise pos to zero as well. Otherwise, strings without a decimal point may not be parsed correctly.
(Finally, copying the string doesn't buy you anything, but introduces the danger of overwriting the temporary buffer of 30 chars.)
回答2:
In addition to M Oehm's answer:
Your str_to_double_func is overly complicated. There is no need to copy the string before doing the conversion.
Here is a simpler version:
#include <stdio.h>
#include <string.h>
double str_to_double_func(char str[])
{
double result = 0;
int len = strlen(str);
int pos = 0, n;
for (n = 0; n < len; n++)
{
if (str[n] == '.')
{
pos = len - n - 1;
}
else
{
result = result * 10.0f + (str[n]-'0');
}
}
while ( pos--)
{
result = result/10.0f;
}
return result;
}
来源:https://stackoverflow.com/questions/31447091/string-to-double-function-returning-infinity-result-in-embedded-compiler