String to double function returning infinity result in embedded compiler

ε祈祈猫儿з 提交于 2019-12-13 10:02:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!