0

I need to convert a string such as "3.456" to a float without atof() or any other string manipulation functions. Below is my code that works for a c string to int conversion but obviously does not work with a float because of the period. What do I need to add to deal with the period? Thank you.

#include <stdio.h>

int size;
char string[] = "345";
int result = 0;
int i = 0;

int findLength(char string[]){

for(size = 0; string[size]!='\0'; size++){

 }
return size;
};

void conversion(char string[]){

result = result * 10 + ( string[i] - '0' );
if (i < size - 1) {
i++;
conversion(string);
 }
}

int main(int argc, const char * argv[]) {
findLength(string);
conversion(string);
printf("%d\n", result);
return 0;
}
Amir Sankar
  • 9
  • 1
  • 4

1 Answers1

0

Before anything else, I think it's important for you to understand how floating point numbers work and how they are represented, at least in C. Look at this question/reply for more information.

Now back to your question. Because of how float are represented in memory, you might not be able to get an exact conversion. That is you might not be able to convert "3.456" to exactly a float that holds the value 3.456. You will only be able to get close to the exact value you want.

First a couple of things wrong with your code:

  • I would stay away from using global variables in my code unless necessary. You defined "size" as a global variable and that's not good practice.
  • Use the standard library strlen function to get the length of a string instead of rewriting a function that does so.

Below, you'll find a working solution. The way to do the conversion is as follow:

  • Scan through the string to get the position of the decimal point
  • If a non-dot character is encountered, add it to the result
  • When you'r done scanning through the string, you need to account for the power of the digits before the decimal point. For example, the first digit before the decimal point is simply added to the result. The second digit before the decimal point is multiplied by 10.0 and added to the result and so on. That is accomplished with a simple while loop as shown in the code.
#include <stdio.h>
#include <string.h>
float stringToFloat(char *string)
{
    float result= 0.0;
    int len = strlen(string);
    int dotPosition = 0;

    for (int i = 0; i < len; i++)
    {
        if (string[i] == '.')
        {
          dotPosition = len - i  - 1;
        }
        else
        {
          result = result * 10.0 + (string[i]-'0');
        }
      }

      while (dotPosition--)
      {
        result /= 10.0;
      }

    return result;
}

int  main()
{
  char string[] = "3.456";

  printf("%f\n",stringToFloat(string));
}

I hope this helps.

P.S: You could increase the precision by using a double instead of a float.

Community
  • 1
  • 1
akinfermo
  • 166
  • 7
  • your response was very helpful thank you! – Amir Sankar Mar 15 '16 at 22:13
  • This works inasmuch as you don't care about getting the so-called "correctly rounded" result. For example, for "1234.56" the correct answer is 1234.56005859375 (if you print all its digits), which is 0x1.34a3d8p10 in hex. Your code returns 1234.5599365234375, or 0x1.34a3d6p+10 in hex; that is one "unit in the last place" below the correct value. (Also, you might want to tack on the 'f' suffix to your literals so your intermediate values are floats and not doubles.) – Rick Regan Mar 16 '16 at 12:27