C语言 将float转换为不带sprintf()的字符串

pjngdqdw  于 2023-08-03  发布在  其他
关注(0)|答案(6)|浏览(137)

我正在编写一个基于微控制器的应用程序,需要将float转换为字符串,但我不需要与sprintf()相关的大量开销。有没有什么好的方法来做到这一点?我不需要太多。我只需要2位数的精度。

mccptt67

mccptt671#

这里有一个针对嵌入式系统优化的版本,它不需要任何stdio或memset,并且内存占用量很低。你负责传递一个用零初始化的字符缓冲区(用指针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上测试。正确地旋转。

bqjvbblv

bqjvbblv2#

试试这个应该又小又好看我直接输出了字符串--做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);
}

字符串

qmelpv7a

qmelpv7a3#

// 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
    }
 }

字符串

kninwzqo

kninwzqo4#

当你们回答的时候,我已经想出了我自己的解决方案,它对我的应用程序更有效,我想我会分享。它不将浮点数转换为字符串,而是将其转换为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

字符串

6jjcrrmo

6jjcrrmo5#

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

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

字符串
在函数的开始。

vvppvyoh

vvppvyoh6#

这是一个小的方法,但它将工作的int和float,decimalPoint参数传递与零值的整数,请让我知道,如果你有比这更小的函数。

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;

}

字符串

相关问题