我正在为基于微控制器的应用程序编码,我需要将float转换为字符串,但是不需要与sprintf()相关的繁重开销。 有什么雄辩的方法可以做到这一点吗? 我不需要太多 我只需要2位数的精度。

===============>>#1 票数:4 已采纳

尝试这个。 它应该很好,也要小。 我直接输出了字符串-做一个printf,而不是sprintf。 我将留给您分配返回字符串的空间,并将结果复制到其中。

// prints a number with 2 digits following the decimal place
// creates the string 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);
}

===============>>#2 票数:1

// convert float to string 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
    }
 }

===============>>#3 票数:1

当你们回答时,我想出了自己的解决方案,该解决方案更适合我的应用程序,我认为我会分享。 它不会将浮点数转换为字符串,而是将其转换为8位整数。 我的数字范围非常小(0-15),并且总是非负数,因此这将允许我通过蓝牙将数据发送到我的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

===============>>#4 票数:1

我无法评论enhzflep的回复,但是要正确处理负数(当前版本没有),您只需添加

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

在函数的开头。

===============>>#5 票数:1

这是一个针对嵌入式系统进行了优化的版本,不需要任何stdio或memset,并且内存占用很少。 您负责将要初始化为零的char缓冲区(使用指针p )传递到要存储字符串的位置,并在创建该缓冲区时定义CHAR_BUFF_SIZE (这样返回的字符串将以null终止)。

static char * _float_to_char(float x, char *p) {
    char *s = p + CHAR_BUFF_SIZE; // go to end of buffer
    uint16_t decimals;  // variable to store the decimals
    int units;  // variable to store the units (part to left of decimal place)
    if (x < 0) { // take care of negative numbers
        decimals = (int)(x * -100) % 100; // make 1000 for 3 decimals etc.
        units = (int)(-1 * x);
    } else { // positive numbers
        decimals = (int)(x * 100) % 100;
        units = (int)x;
    }

    *--s = (decimals % 10) + '0';
    decimals /= 10; // repeat for as many decimal places as you need
    *--s = (decimals % 10) + '0';
    *--s = '.';

    while (units > 0) {
        *--s = (units % 10) + '0';
        units /= 10;
    }
    if (x < 0) *--s = '-'; // unary minus sign for negative numbers
    return s;
}

在ARM Cortex M0和M4上进行了测试。 正确舍入。

===============>>#6 票数:0

它是一个Liitle大型方法,但它对于int和float都适用,为十进制Point参数传递的Integer值为零,请让我知道您的函数是否小于此值。

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;

}

  ask by audiFanatic translate from so

未解决问题?本站智能推荐: