Conversion de float en chaîne sans sprintf ()

Je suis en train de coder pour une application basée sur un microcontrôleur et je dois convertir un float en chaîne de caractères, mais je n’ai pas besoin de la lourde charge associée à sprintf (). Y at-il un moyen éloquent de faire cela? Je n’ai pas besoin de trop. Je n’ai besoin que de 2 chiffres de précision.

Essaye ça. Ça devrait être beau et petit. J’ai sorti la chaîne directement – en faisant un printf, plutôt qu’un sprintf. Je vous laisse le soin d’allouer de l’espace pour la chaîne de retour et de copier le résultat dans celle-ci.

 // prints a number with 2 digits following the decimal place // creates the ssortingng backwards, before printing it character-by-character from // the end to the start // // Usage: myPrintf(270.458) // Output: 270.45 void myPrintf(float fVal) { char result[100]; int dVal, dec, i; fVal += 0.005; // added after a comment from Matt McNabb, see below. dVal = fVal; dec = (int)(fVal * 100) % 100; memset(result, 0, 100); result[0] = (dec % 10) + '0'; result[1] = (dec / 10) + '0'; result[2] = '.'; i = 3; while (dVal > 0) { result[i] = (dVal % 10) + '0'; dVal /= 10; i++; } for (i=strlen(result)-1; i>=0; i--) putc(result[i], stdout); } 
 // convert float to ssortingng one decimal digit at a time // assumes float is < 65536 and ARRAYSIZE is big enough // problem: it truncates numbers at size without rounding // str is a char array to hold the result, float is the number to convert // size is the number of decimal digits you want void FloatToStringNew(char *str, float f, char size) { char pos; // position in string char len; // length of decimal part of result char* curr; // temp holder for next digit int value; // decimal digit(s) to convert pos = 0; // initialize pos, just to be sure value = (int)f; // truncate the floating point number itoa(value,str); // this is kinda dangerous depending on the length of str // now str array has the digits before the decimal if (f < 0 ) // handle negative numbers { f *= -1; value *= -1; } len = strlen(str); // find out how big the integer part was pos = len; // position the pointer to the end of the integer part str[pos++] = '.'; // add decimal point to string while(pos < (size + len + 1) ) // process remaining digits { f = f - (float)value; // hack off the whole part of the number f *= 10; // move next digit over value = (int)f; // get next digit itoa(value, curr); // convert digit to string str[pos++] = *curr; // add digit to result string and increment pointer } } 

Pendant que vous répondiez, j’ai mis au point ma propre solution qui convient mieux à mon application et que je pense partager. Il ne convertit pas le float en chaîne, mais en nombres entiers de 8 bits. Ma gamme de chiffres est très petite (0-15) et toujours non négative. Cela me permettra donc d’envoyer les données via Bluetooth à mon application Android.

 //Assumes bytes* is at least 2-bytes long void floatToBytes(byte_t* bytes, float flt) { bytes[1] = (byte_t) flt; //truncate whole numbers flt = (flt - bytes[1])*100; //remove whole part of flt and shift 2 places over bytes[0] = (byte_t) flt; //truncate the fractional part from the new "whole" part } //Example: 144.2345 -> bytes[1] = 144; -> bytes[0] = 23 

Je ne peux pas commenter la réponse de enhzflep, mais pour gérer correctement les nombres négatifs (ce que la version actuelle ne permet pas), il vous suffit d’append

 if (fVal < 0) { putc('-', stdout); fVal = -fVal; } 

au début de la fonction.

C’est une grande méthode Liitle, mais cela fonctionnerait à la fois pour int et float, le paramètre decimalPoint est passé avec une valeur nulle pour Integer. Merci de me faire savoir si vous avez une fonction plus petite que celle-ci.

 void floatToStr(uint8_t *out, float x,int decimalPoint) { uint16_t absval = fabs(x); uint16_t absvalcopy = absval; int decimalcount = 0; while(absvalcopy != 0) { absvalcopy /= 10; decimalcount ++; } uint8_t *absbuffer = malloc(sizeof(uint8_t) * (decimalcount + decimalPoint + 1)); int absbufferindex = 0; absvalcopy = absval; uint8_t temp; int i = 0; for(i = decimalcount; i > 0; i--) { uint16_t frst1 = fabs((absvalcopy / pow(10.0, i-1))); temp = (frst1 % 10) + 0x30; *(absbuffer + absbufferindex) = temp; absbufferindex++; } if(decimalPoint > 0) { *(absbuffer + absbufferindex) = '.'; absbufferindex ++; //------------------- Decimal Extractor ---------------------// for(i = 1; i < decimalPoint + 1; i++) { uint32_t valueFloat = (x - (float)absval)*pow(10,i); *(absbuffer + absbufferindex) = ((valueFloat) % 10) + 0x30; absbufferindex++; } } for(i=0; i< (decimalcount + decimalPoint + 1); i++) { *(out + i) = *(absbuffer + i); } i=0; if(decimalPoint > 0) i = 1; *(out + decimalcount + decimalPoint + i) = 0; }