[技术问答] 浮点数转字符串函数

[复制链接]
4685|40
 楼主| 1988020566 发表于 2024-8-11 15:30 | 显示全部楼层 |阅读模式

单片机浮点数转字符串可以使用 stdio.h 中sprintf函数,但代码体积和RAM占用空间比较大。自己写的程序又不太好。在学习GPS数据解析过程中用到了LeiOuYang的GPS解析库,在其中有浮点数转字符串函数,现推荐给大家。

一下是完整的基于KEIL C51 的C文件:

//#include //#include //使用sprintf时取消该注释

#define DIGITAL_TO_CHAR(x) ( (x)+'0' )

unsigned char DispBuff[5];

/* 多次方 */

static int int_pow(int value, unsigned int count)

{

int v = 1;

while(count--)

v = v*value;

return v;

}

/* 浮点数转换为字符串,包括整数转换为字符串

* intgr指定整数位个数,dec指定小数位个数

* 自动去除前面的0,小数点后面的0不会舍去

*/

static unsigned char float_to_string(double value, char* pdest, unsigned int intgr, unsigned int dec)

{

char* pstr = (void*)0;

double fvalue = 0.0;

char c = 0;

unsigned int tvalue = 0;

unsigned char zeroflag = 0;

unsigned int tm = 0;

if( (void*)0==pdest || 0==intgr ) return 0;

if(dec>9) dec = 9;

if(1==intgr) zeroflag = 1;

pstr = pdest;

if(value

编译结果:

仿真结果:

而使用sprintf的程序,

#include unsigned char DispBuff[5];

void main()

{

sprintf(DispBuff,"%.1f",10.1);

while(1);

}

编译结果:


可怜的小弗朗士 发表于 2024-8-12 13:49 | 显示全部楼层
这个实用,一直在浮点转字符串出问题
jkl21 发表于 2024-8-12 20:37 | 显示全部楼层
使用snprintf或snprintf_s而不是sprintf,因为前者可以防止缓冲区溢出,这在处理用户输入或不可信数据时尤为重要。
班杰明 发表于 2024-8-12 22:45 来自手机 | 显示全部楼层
_s的函数最低支持哪个标准啊?
gygp 发表于 2024-8-12 23:23 | 显示全部楼层
如果在函数中动态分配内存来存储转换后的字符串,务必在使用完毕后进行释放,以避免内存泄漏。
pixhw 发表于 2024-8-13 01:17 | 显示全部楼层
注意不同平台上的浮点数表示可能略有不同,这可能会影响到转换后的字符串。例如,某些平台可能在显示浮点数时使用不同的舍入规则。
i1mcu 发表于 2024-8-13 04:58 | 显示全部楼层
与sprintf相似,但snprintf允许指定最大的字符串长度,从而避免缓冲区溢出的风险。其用法为snprintf(char *str, size_t size, const char *format, float value),在这里size参数尤其重要,它限制了输出字符串的最大长度。
jonas222 发表于 2024-8-13 08:29 | 显示全部楼层
使用sprintf时,如果目标缓冲区不够大,可能会导致缓冲区溢出。建议使用snprintf,它可以防止写入超出缓冲区大小的内容。
uytyu 发表于 2024-8-13 11:08 | 显示全部楼层
可以通过在格式化字符串中指定小数点后的位数来控制输出精度。
timfordlare 发表于 2024-8-13 14:51 | 显示全部楼层
常用函数
printf()
用于标准输出,但也可以用于格式化字符串。
示例:printf("%f", float_value);
snprintf()
安全的字符串格式化函数,限制输出字符串的最大长度。
示例:snprintf(buffer, size, "%f", float_value);
sprintf()
类似于printf(),但直接写入到缓冲区。
示例:sprintf(buffer, "%f", float_value);
sesefadou 发表于 2024-8-13 20:18 | 显示全部楼层
由于浮点数的表示是近似的,直接转换可能会丢失一些精度。在进行转换之前,确定是否需要对数值进行四舍五入或截断,以符合期望的精确度。例如,使用snprintf(str, sizeof(str), "%.2f", value)可将浮点数保留两位小数。
tabmone 发表于 2024-8-13 22:35 | 显示全部楼层
#include <stdio.h>
#include <math.h>
#include <string.h>

void safeFloatToString(double value, char *buffer, size_t size) {
    // 检查是否为NaN或Infinity
    if (isnan(value)) {
        snprintf(buffer, size, "NaN");
    } else if (isinf(value)) {
        snprintf(buffer, size, value > 0 ? "+Inf" : "-Inf");
    } else {
        // 保留两位小数,确保不会超出缓冲区
        snprintf(buffer, size, "%.2f", value);
    }
}

int main() {
    double float_value = 123.456;
    char buffer[50];

    safeFloatToString(float_value, buffer, sizeof(buffer));
    printf("Converted string: %s\n", buffer);

    return 0;
}
ulystronglll 发表于 2024-8-15 13:12 | 显示全部楼层
如果需要在循环中频繁地将浮点数转换为字符串,考虑性能影响。可能需要优化缓冲区的分配和重用
qiufengsd 发表于 2024-8-15 16:38 | 显示全部楼层
对于浮点数,通常使用%f、%e或%g等格式说明符。每个说明符都有其特点和用途,比如%f用于固定点表示法,%e用于科学计数法,而%g则根据值的大小自动选择更紧凑的表示方式。
cemaj 发表于 2024-8-17 15:40 | 显示全部楼层
可以通过格式化字符串中的.和随后的数字来指定,例如%.2f表示保留两位小数。
51xlf 发表于 2024-8-17 19:34 | 显示全部楼层
特别是对小数部分的处理,需要考虑进位影响整数部分的情况。实现一个自定义的转换函数时,应从最低位开始处理,逐步向高位推算,同时标记和处理进位。
nomomy 发表于 2024-8-17 21:30 | 显示全部楼层
虽然性能通常不是将浮点数转换为字符串时的首要考虑因素,但在性能敏感的应用程序中,应该评估使用sprintf或snprintf的开销,并考虑是否有更高效的方法
mmbs 发表于 2024-8-18 11:07 | 显示全部楼层
nprintf()函数的第一个参数是一个格式化字符串,用于指定输出的格式。对于浮点数,可以使用%f、%e、%E、%g或%G等格式说明符。
xiaoyaodz 发表于 2024-8-18 18:03 | 显示全部楼层
%f用于格式化浮点数,但还有其他选项,如%e(科学计数法)和%g(自动选择%f或%e中最紧凑的形式)。
pmp 发表于 2024-8-18 21:09 | 显示全部楼层
使用sprintf时,需要确保目标缓冲区足够大以存储转换后的字符串(包括空终止符\0)。否则,可能会导致缓冲区溢出,这是安全漏洞的常见来源。相比之下,snprintf通过允许你指定目标缓冲区的大小来避免这个问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

423

主题

11042

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部