#include <stdio.h>
/*
Because lcd and serial don't support printf, and its very costly, and all we need
is simple formating with a certain number of digits and precision, this ftoa is enough.
If digits is negative, it will pad left.
*/
#define BUF_LEN 100
char buf[BUF_LEN]; //need a buffer to hold formatted strings to send to LCD
#define absq(amt) ((amt)<0?0-(amt):(amt))
int ftoa( char * str, //buffer to hold result.
float f, //input value
char digits, //total number of digits
char precision //digits right of decimal
) {
long pow10[10] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
char i=0,k,l=0;
unsigned int a,c;
unsigned char b;
char decimal='.';
char pad=' '; //could be a parameter to support custom padding character.
if((sizeof(pow10)/sizeof(pow10[0]))<=absq(digits)) {//larger pow10 table needed
str[i++]='O';
str[i]='\0';
return i;
};
// check for negative float
if(f<0.0) { //is it negative?
str[i++]='-'; //indicate
f*=-1; //make it positive
(0<digits?digits--:digits++); //optional, steal digit for sign, keep length
}
a=(unsigned int)f;// extracting whole number
f-=a; // extracting decimal part
k = digits;
// number of digits in whole number
while(k>0) { //note this doesn't happen if digits was negative: Padding.
c = pow10[k];
c = a/c;
if(c>0) { break; }
k--;
} // number of digits in whole number are k+1
/*
extracting most significant digit i.e. right most digit , and concatenating to string
obtained as quotient by dividing number by 10^k where k = (number of digit -1)
*/
for(l=absq(k);l>=0;l--){
c = pow10[l]; //get the next power
b = a/c; //get the next digit
if (b>0) pad='0'; //stop padding after first digit.
if (b>10) b='e'-'0';//overflow
str[i++]=(l&&!b?pad:b+'0'); //digit or pad, l&& adds leading zero for fractions
a%=c; //modulo by power
}
if (precision) {str[i++] = decimal;};
/* extracting decimal digits till precision */
if (0>precision) {k=0; precision=0-precision;}
for(l=precision;0<l;l--) {
f*=(float)10.0;
b = (int)(f); //math floor so round half way
str[i++]=b+'0'; //convert to ASCII
f-=(int)f;
if (k && 0.00001>f) { break; } //nothing left, save chars.
//0==f won't work if there are any floating point errors.
}
str[i]='\0'; //null terminate the buffer
return i;
}
int main(void) {
int i;
float f;
i=0;
for (f=0.0001;f<0.00091;f+=0.0001) {
ftoa(buf+i, f, 5, -4);buf[i+6]=' ';i+=7;buf[i]=0;
}
i=0;
for (f=0.001;f<0.0091;f+=0.001) {
ftoa(buf+i, f, 5, -4);buf[i+6]=' ';i+=7;buf[i]=0;
}
i=0;
for (f=0.01;f<0.091;f+=0.01) {
ftoa(buf+i, f, 5, -4);buf[i+6]=' ';i+=7;buf[i]=0;
}
i=0;
for (f=0.1;f<0.91;f+=0.1) {
ftoa(buf+i, f, 5, -4);buf[i+6]=' ';i+=7;buf[i]=0;
}
ftoa(buf, .12345, 0, 4);buf[6]=' ';
ftoa(buf+7, .12345, 0, 3);buf[12]=' ';
ftoa(buf+13, .12345, 0, 2);buf[17]=' ';
ftoa(buf+18, .12345, 0, 1);buf[21]=' ';
ftoa
(buf
+22, .12345, 0, 0);puts(buf
); ftoa
(buf
, -4404.322, -8, -4);puts(buf
); ftoa
(buf
, 4000123.1014, -3, 3);puts(buf
); ftoa
(buf
, 4000123.1014, 9, 3);puts(buf
); return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CgovKgpCZWNhdXNlIGxjZCBhbmQgc2VyaWFsIGRvbid0IHN1cHBvcnQgcHJpbnRmLCBhbmQgaXRzIHZlcnkgY29zdGx5LCBhbmQgYWxsIHdlIG5lZWQKaXMgc2ltcGxlIGZvcm1hdGluZyB3aXRoIGEgY2VydGFpbiBudW1iZXIgb2YgZGlnaXRzIGFuZCBwcmVjaXNpb24sIHRoaXMgZnRvYSBpcyBlbm91Z2guCklmIGRpZ2l0cyBpcyBuZWdhdGl2ZSwgaXQgd2lsbCBwYWQgbGVmdC4KKi8KI2RlZmluZSAgQlVGX0xFTiAxMDAKY2hhciBidWZbQlVGX0xFTl07IC8vbmVlZCBhIGJ1ZmZlciB0byBob2xkIGZvcm1hdHRlZCBzdHJpbmdzIHRvIHNlbmQgdG8gTENECiNkZWZpbmUgYWJzcShhbXQpICgoYW10KTwwPzAtKGFtdCk6KGFtdCkpCgppbnQgZnRvYSgJY2hhciAqIHN0ciwgCS8vYnVmZmVyIHRvIGhvbGQgcmVzdWx0LgoJZmxvYXQgZiwgICAgCS8vaW5wdXQgdmFsdWUKCWNoYXIgZGlnaXRzLAkvL3RvdGFsIG51bWJlciBvZiBkaWdpdHMKCWNoYXIgcHJlY2lzaW9uCS8vZGlnaXRzIHJpZ2h0IG9mIGRlY2ltYWwKCSkgewpsb25nIHBvdzEwWzEwXSA9IHsxLDEwLDEwMCwxMDAwLDEwMDAwLDEwMDAwMCwxMDAwMDAwLDEwMDAwMDAwLDEwMDAwMDAwMCwxMDAwMDAwMDAwfTsKY2hhciBpPTAsayxsPTA7CnVuc2lnbmVkIGludCBhLGM7CnVuc2lnbmVkIGNoYXIgYjsKY2hhciBkZWNpbWFsPScuJzsKY2hhciBwYWQ9JyAnOyAvL2NvdWxkIGJlIGEgcGFyYW1ldGVyIHRvIHN1cHBvcnQgY3VzdG9tIHBhZGRpbmcgY2hhcmFjdGVyLgoKICBpZigoc2l6ZW9mKHBvdzEwKS9zaXplb2YocG93MTBbMF0pKTw9YWJzcShkaWdpdHMpKSB7Ly9sYXJnZXIgcG93MTAgdGFibGUgbmVlZGVkCiAgCXN0cltpKytdPSdPJzsKICAJc3RyW2ldPSdcMCc7CiAgCXJldHVybiBpOwogIAl9OyAKICAvLyBjaGVjayBmb3IgbmVnYXRpdmUgZmxvYXQKICBpZihmPDAuMCkgeyAvL2lzIGl0IG5lZ2F0aXZlPwogICAgc3RyW2krK109Jy0nOyAvL2luZGljYXRlCiAgICBmKj0tMTsgLy9tYWtlIGl0IHBvc2l0aXZlCiAgICAoMDxkaWdpdHM/ZGlnaXRzLS06ZGlnaXRzKyspOyAvL29wdGlvbmFsLCBzdGVhbCBkaWdpdCBmb3Igc2lnbiwga2VlcCBsZW5ndGgKICAgIH0KICBhPSh1bnNpZ25lZCBpbnQpZjsvLyBleHRyYWN0aW5nIHdob2xlIG51bWJlcgogIGYtPWE7CS8vIGV4dHJhY3RpbmcgZGVjaW1hbCBwYXJ0CiAgayA9IGRpZ2l0czsKICAvLyBudW1iZXIgb2YgZGlnaXRzIGluIHdob2xlIG51bWJlcgogIHdoaWxlKGs+MCkgeyAvL25vdGUgdGhpcyBkb2Vzbid0IGhhcHBlbiBpZiBkaWdpdHMgd2FzIG5lZ2F0aXZlOiBQYWRkaW5nLgogICAgYyA9IHBvdzEwW2tdOwogICAgYyA9IGEvYzsKICAgIGlmKGM+MCkgeyBicmVhazsgfQogICAgay0tOwogICAgfSAvLyBudW1iZXIgb2YgZGlnaXRzIGluIHdob2xlIG51bWJlciBhcmUgaysxCi8qCmV4dHJhY3RpbmcgbW9zdCBzaWduaWZpY2FudCBkaWdpdCBpLmUuIHJpZ2h0IG1vc3QgZGlnaXQgLCBhbmQgY29uY2F0ZW5hdGluZyB0byBzdHJpbmcKb2J0YWluZWQgYXMgcXVvdGllbnQgYnkgZGl2aWRpbmcgbnVtYmVyIGJ5IDEwXmsgd2hlcmUgayA9IChudW1iZXIgb2YgZGlnaXQgLTEpCiovCiAgZm9yKGw9YWJzcShrKTtsPj0wO2wtLSl7CiAgICBjID0gcG93MTBbbF07CS8vZ2V0IHRoZSBuZXh0IHBvd2VyCiAgICBiID0gYS9jOwkvL2dldCB0aGUgbmV4dCBkaWdpdAogICAgaWYgKGI+MCkgcGFkPScwJzsJLy9zdG9wIHBhZGRpbmcgYWZ0ZXIgZmlyc3QgZGlnaXQuCiAgICBpZiAoYj4xMCkgYj0nZSctJzAnOy8vb3ZlcmZsb3cKICAgIHN0cltpKytdPShsJiYhYj9wYWQ6YisnMCcpOyAvL2RpZ2l0IG9yIHBhZCwgbCYmIGFkZHMgbGVhZGluZyB6ZXJvIGZvciBmcmFjdGlvbnMKICAgIGElPWM7ICAgCS8vbW9kdWxvIGJ5IHBvd2VyCiAgICB9CiAgaWYgKHByZWNpc2lvbikge3N0cltpKytdID0gZGVjaW1hbDt9OwovKiBleHRyYWN0aW5nIGRlY2ltYWwgZGlnaXRzIHRpbGwgcHJlY2lzaW9uICovCiAgaWYgKDA+cHJlY2lzaW9uKSB7az0wOyBwcmVjaXNpb249MC1wcmVjaXNpb247fQogIGZvcihsPXByZWNpc2lvbjswPGw7bC0tKSB7CiAgICBmKj0oZmxvYXQpMTAuMDsKICAgIGIgPSAoaW50KShmKTsgLy9tYXRoIGZsb29yIHNvIHJvdW5kIGhhbGYgd2F5CiAgICBzdHJbaSsrXT1iKycwJzsgLy9jb252ZXJ0IHRvICBBU0NJSQogICAgZi09KGludClmOwogICAgaWYgKGsgJiYgMC4wMDAwMT5mKSB7IGJyZWFrOyB9IC8vbm90aGluZyBsZWZ0LCBzYXZlIGNoYXJzLgogICAgLy8wPT1mIHdvbid0IHdvcmsgaWYgdGhlcmUgYXJlIGFueSBmbG9hdGluZyBwb2ludCBlcnJvcnMuCiAgICB9CiAgc3RyW2ldPSdcMCc7IC8vbnVsbCB0ZXJtaW5hdGUgdGhlIGJ1ZmZlcgogIHJldHVybiBpOwogIH0KCgppbnQgbWFpbih2b2lkKSB7CmludCBpOwpmbG9hdCBmOwoJaT0wOwoJZm9yIChmPTAuMDAwMTtmPDAuMDAwOTE7Zis9MC4wMDAxKSB7CgkJZnRvYShidWYraSwgZiwgNSwgLTQpO2J1ZltpKzZdPScgJztpKz03O2J1ZltpXT0wOwoJCX0KCXB1dHMoYnVmKTsKCWk9MDsKCWZvciAoZj0wLjAwMTtmPDAuMDA5MTtmKz0wLjAwMSkgewoJCWZ0b2EoYnVmK2ksIGYsIDUsIC00KTtidWZbaSs2XT0nICc7aSs9NztidWZbaV09MDsKCQl9CglwdXRzKGJ1Zik7CglpPTA7Cglmb3IgKGY9MC4wMTtmPDAuMDkxO2YrPTAuMDEpIHsKCQlmdG9hKGJ1ZitpLCBmLCA1LCAtNCk7YnVmW2krNl09JyAnO2krPTc7YnVmW2ldPTA7CgkJfQoJcHV0cyhidWYpOwoJaT0wOwoJZm9yIChmPTAuMTtmPDAuOTE7Zis9MC4xKSB7CgkJZnRvYShidWYraSwgZiwgNSwgLTQpO2J1ZltpKzZdPScgJztpKz03O2J1ZltpXT0wOwoJCX0KCXB1dHMoYnVmKTsKCWZ0b2EoYnVmLCAuMTIzNDUsIDAsIDQpO2J1Zls2XT0nICc7CglmdG9hKGJ1Zis3LCAuMTIzNDUsIDAsIDMpO2J1ZlsxMl09JyAnOwoJZnRvYShidWYrMTMsIC4xMjM0NSwgMCwgMik7YnVmWzE3XT0nICc7CglmdG9hKGJ1ZisxOCwgLjEyMzQ1LCAwLCAxKTtidWZbMjFdPScgJzsKCWZ0b2EoYnVmKzIyLCAuMTIzNDUsIDAsIDApO3B1dHMoYnVmKTsKCWZ0b2EoYnVmLCAtNDQwNC4zMjIsIC04LCAtNCk7cHV0cyhidWYpOwoJZnRvYShidWYsIDQwMDAxMjMuMTAxNCwgLTMsIDMpO3B1dHMoYnVmKTsKCWZ0b2EoYnVmLCA0MDAwMTIzLjEwMTQsIDksIDMpO3B1dHMoYnVmKTsKCXJldHVybiAwOwp9Cg==