// floatToString.h // // Tim Hirzel // tim@growdown.com // March 2008 // float to string // // If you don't save this as a .h, you will want to remove the default arguments // uncomment this first line, and swap it for the next. I don't think keyword arguments compile in .pde files #include "floatToString.h" char * floatToString(char * outstr, float value, int places, int minwidth, bool rightjustify, bool terminate) { // this is used to write a float value to string, outstr. oustr is also the return value. int digit; float tens = 0.1; int tenscount = 0; int i; float tempfloat = value; int c = 0; int charcount = 1; int extra = 0; // make sure we round properly. this could use pow from , but doesn't seem worth the import // if this rounding step isn't here, the value 54.321 prints as 54.3209 // calculate rounding term d: 0.5/pow(10,places) float d = 0.5; if (value < 0) d *= -1.0; // divide by ten for each decimal place for (i = 0; i < places; i++) d/= 10.0; // this small addition, combined with truncation will round our values properly tempfloat += d; // first get value tens to be the large power of ten less than value if (value < 0) tempfloat *= -1.0; while ((tens * 10.0) <= tempfloat) { tens *= 10.0; tenscount += 1; } if (tenscount > 0) charcount += tenscount; else charcount += 1; if (value < 0) charcount += 1; // for '-' if (places > 0) charcount += 1 + places; // for '.' and n places minwidth += 1; // both count the null final character if (minwidth > charcount){ extra = minwidth - charcount ; charcount = minwidth; } if (extra > 0 and rightjustify) { for (int i = 0; i< extra; i++) { outstr[c++] = ' '; } } // write out the negative if needed if (value < 0) outstr[c++] = '-'; if (tenscount == 0) outstr[c++] = '0'; for (i=0; i< tenscount; i++) { digit = (int) (tempfloat/tens); itoa(digit, &outstr[c++], 10); tempfloat = tempfloat - ((float)digit * tens); tens /= 10.0; } // if no places after decimal, stop now and return // otherwise, write the point and continue on if (places > 0) outstr[c++] = '.'; // now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value for (i = 0; i < places; i++) { tempfloat *= 10.0; digit = (int) tempfloat; itoa(digit, &outstr[c++], 10); // once written, subtract off that digit tempfloat = tempfloat - (float) digit; } if (extra > 0 and not rightjustify) { for (int i = 0; i< extra; i++) { outstr[c++] = ' '; } } if (terminate) outstr[c++] = '\0'; return outstr; } /* EXAMPLE APPLICATION #include "floatToString.h" //set to whatever is the location of floatToStrig void setup() { Serial.begin(9600); char buffer[25]; // just give it plenty to write out any values you want to test // ========================================== // now run a series on the floatToString function // looking at the precision of the float Serial.println("floatToString(buffer, 1000000.321 , 5);"); Serial.println(floatToString(buffer, 1000000.321, 5)); Serial.println(); Serial.println("floatToString(buffer, 100000.321 , 5);"); Serial.println(floatToString(buffer, 100000.321, 5)); Serial.println(); Serial.println("floatToString(buffer, 10000.321 , 5);"); Serial.println(floatToString(buffer, 10000.321, 5)); Serial.println(); Serial.println("floatToString(buffer, 1000.321 , 5);"); Serial.println(floatToString(buffer, 1000.321, 5)); Serial.println(); Serial.println("floatToString(buffer, 100.321 , 5);"); Serial.println(floatToString(buffer, 100.321, 5)); Serial.println(); // ========================================== // looking at effect of changing precision Serial.println("floatToString(buffer, 100000.321 , 6);"); Serial.println(floatToString(buffer, 100000.321, 6)); Serial.println(); Serial.println("floatToString(buffer, 100000.321 , 7);"); Serial.println(floatToString(buffer, 100000.321, 7)); Serial.println(); Serial.println("floatToString(buffer, 100000.321 , 8);"); Serial.println(floatToString(buffer, 100000.321, 8)); Serial.println(); Serial.println("floatToString(buffer, 100000.321 , 9);"); Serial.println(floatToString(buffer, 100000.321, 9)); Serial.println(); // ========================================== // check negatives and rounding, and some edge cases Serial.println("floatToString(buffer, -5004.321 , 5);"); Serial.println(floatToString(buffer, -5004.321 , 5)); Serial.println(); Serial.println("floatToString(buffer, 99.999 , 3); "); Serial.println(floatToString(buffer, 99.999 , 3)); Serial.println(); Serial.println("floatToString(buffer, 100, 1);"); Serial.println(floatToString(buffer, 100, 1)); Serial.println(); Serial.println("floatToString(buffer, -100.999 , 1);"); Serial.println(floatToString(buffer, -100.999 , 1)); Serial.println(); Serial.println("floatToString(buffer, -54.321 , 0);"); Serial.println(floatToString(buffer, -54.321 , 0)); Serial.println(); Serial.println("floatToString(buffer, 0.321 , 5);"); Serial.println(floatToString(buffer, 0.321 , 5)); Serial.println(); Serial.println("floatToString(buffer, -1.0001 , 5);"); Serial.println(floatToString(buffer, -1.0001 , 5)); Serial.println(); Serial.println("floatToString(buffer, -0.000001 , 5);"); Serial.println(floatToString(buffer, -0.000001 , 5)); Serial.println(); Serial.println("floatToString(buffer, 0.000001 , 5);"); Serial.println(floatToString(buffer, 0.000001 , 5)); Serial.println(); Serial.println("floatToString(buffer, -0.00001 , 5);"); Serial.println(floatToString(buffer, -0.00001 , 5)); Serial.println(); Serial.println("floatToString(buffer, 0.000099 , 5);"); Serial.println(floatToString(buffer, 0.000099 , 5)); Serial.println(); // alternative technique that depends on //Serial.println("Serial.println(dtostrf(-1.0001, 2, 5, s));"); //char s[32]; // Serial.println(dtostrf(-1.0001, 2, 5, s))); delay(1000); Serial.println(); } void loop() { } */