Go Down

Topic: ftoa (Read 1 time) previous topic - next topic

Martin Waller

Jun 11, 2011, 05:42 pm Last Edit: Jun 11, 2011, 06:58 pm by Martin Waller Reason: 1
I've been looking around for a ftoa function. The ones that I found seemed to fail for numbers such as 0.05, you'd get 0.5, it would loose any leading zeros in the fraction. Below is a version that should fix this.

Code: [Select]

char *ftoa(char *buffer, double d, int precision) {

long wholePart = (long) d;

// Deposit the whole part of the number.

itoa(wholePart,buffer,10);

// Now work on the faction if we need one.

if (precision > 0) {

// We do, so locate the end of the string and insert
// a decimal point.

char *endOfString = buffer;
while (*endOfString != '\0') endOfString++;
*endOfString++ = '.';

// Now work on the fraction, be sure to turn any negative
// values positive.

if (d < 0) {
d *= -1;
wholePart *= -1;
}

double fraction = d - wholePart;
while (precision > 0) {

// Multipleby ten and pull out the digit.

fraction *= 10;
wholePart = (long) fraction;
*endOfString++ = '0' + wholePart;

// Update the fraction and move on to the
// next digit.

fraction -= wholePart;
precision--;
}

// Terminate the string.

*endOfString = '\0';
}

   return buffer;
}


Martin Waller

Sorry, I developed this in Microsoft C++ Express, you will need to remove the leading _ on the call to itoa! Sorry!

mowcius

You still should be able to click modify and alter your post.

Also please use the [code ][/code ] tags

samarkh

Hi Martin,
Can you give an example of how to use?

Yours Simon M.

davekw7x

#4
Jun 15, 2011, 05:11 pm Last Edit: Jun 15, 2011, 05:46 pm by davekw7x Reason: 1

I've been looking around for a ftoa function.

The avr-libc library used with Arduino has two such conversion functions: dtostre() for scientific notation and dtstrf() for fixed point.

Quote from: Martin Waller
...Below is a version...

I would like to see rounded values in the output.

So, if I had a number, say, 0.014567 and I wanted three decimal places I think it should be 0.015.  With four decimal places I would expect to see 0.0146. Stuff like that.

Code: [Select]
void setup()
{
   Serial.begin(9600);
   float x = 0.014567;
   Serial.println("x was set to 0.014567");
   Serial.println("Here are results with ftoa, dtostrf and dtostre");
   Serial.println();

   char buffer[30]; // Could be smaller, but...
   for (int i = 0; i < 7; i++) {

       ftoa(buffer, x, i);
       Serial.print(buffer);
       Serial.print("  ");
       dtostrf(x, i+4, i, buffer); // avr-libc function for floats
       Serial.print(buffer);
       Serial.print("  ");
       dtostre(x, buffer, i, NULL); // avr-libc function for scientific notation
       Serial.println(buffer);

   }
}

void loop() {}

// Your ftoa goes here



Output:

x was set to 0.014567
Here are results with ftoa, dtostrf and dtostre

0     0  1e-02
0.0    0.0  1.5e-02
0.01    0.01  1.46e-02
0.014    0.015  1.457e-02
0.0145    0.0146  1.4567e-02
0.01456    0.01457  1.45670e-02
0.014566    0.014567  1.456700e-02



Bottom line: It's interesting, but, as a general purpose conversion routine it has a few problems other than my preference for rounding.  What happens if you give it x = 1234567.0?  That one is pretty easy to fix, I'm thinking (don't forget to test -1234567.0 also).


Regards,

Dave


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy