问题
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