打印
[技术问答]

浮点数转字符串函数

[复制链接]
2493|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的函数最低支持哪个标准啊?

使用特权

评论回复
5
gygp| | 2024-8-12 23:23 | 只看该作者
如果在函数中动态分配内存来存储转换后的字符串,务必在使用完毕后进行释放,以避免内存泄漏。

使用特权

评论回复
6
pixhw| | 2024-8-13 01:17 | 只看该作者
注意不同平台上的浮点数表示可能略有不同,这可能会影响到转换后的字符串。例如,某些平台可能在显示浮点数时使用不同的舍入规则。

使用特权

评论回复
7
i1mcu| | 2024-8-13 04:58 | 只看该作者
与sprintf相似,但snprintf允许指定最大的字符串长度,从而避免缓冲区溢出的风险。其用法为snprintf(char *str, size_t size, const char *format, float value),在这里size参数尤其重要,它限制了输出字符串的最大长度。

使用特权

评论回复
8
jonas222| | 2024-8-13 08:29 | 只看该作者
使用sprintf时,如果目标缓冲区不够大,可能会导致缓冲区溢出。建议使用snprintf,它可以防止写入超出缓冲区大小的内容。

使用特权

评论回复
9
uytyu| | 2024-8-13 11:08 | 只看该作者
可以通过在格式化字符串中指定小数点后的位数来控制输出精度。

使用特权

评论回复
10
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);

使用特权

评论回复
11
sesefadou| | 2024-8-13 20:18 | 只看该作者
由于浮点数的表示是近似的,直接转换可能会丢失一些精度。在进行转换之前,确定是否需要对数值进行四舍五入或截断,以符合期望的精确度。例如,使用snprintf(str, sizeof(str), "%.2f", value)可将浮点数保留两位小数。

使用特权

评论回复
12
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;
}

使用特权

评论回复
13
ulystronglll| | 2024-8-15 13:12 | 只看该作者
如果需要在循环中频繁地将浮点数转换为字符串,考虑性能影响。可能需要优化缓冲区的分配和重用

使用特权

评论回复
14
qiufengsd| | 2024-8-15 16:38 | 只看该作者
对于浮点数,通常使用%f、%e或%g等格式说明符。每个说明符都有其特点和用途,比如%f用于固定点表示法,%e用于科学计数法,而%g则根据值的大小自动选择更紧凑的表示方式。

使用特权

评论回复
15
cemaj| | 2024-8-17 15:40 | 只看该作者
可以通过格式化字符串中的.和随后的数字来指定,例如%.2f表示保留两位小数。

使用特权

评论回复
16
51xlf| | 2024-8-17 19:34 | 只看该作者
特别是对小数部分的处理,需要考虑进位影响整数部分的情况。实现一个自定义的转换函数时,应从最低位开始处理,逐步向高位推算,同时标记和处理进位。

使用特权

评论回复
17
nomomy| | 2024-8-17 21:30 | 只看该作者
虽然性能通常不是将浮点数转换为字符串时的首要考虑因素,但在性能敏感的应用程序中,应该评估使用sprintf或snprintf的开销,并考虑是否有更高效的方法

使用特权

评论回复
18
mmbs| | 2024-8-18 11:07 | 只看该作者
nprintf()函数的第一个参数是一个格式化字符串,用于指定输出的格式。对于浮点数,可以使用%f、%e、%E、%g或%G等格式说明符。

使用特权

评论回复
19
xiaoyaodz| | 2024-8-18 18:03 | 只看该作者
%f用于格式化浮点数,但还有其他选项,如%e(科学计数法)和%g(自动选择%f或%e中最紧凑的形式)。

使用特权

评论回复
20
pmp| | 2024-8-18 21:09 | 只看该作者
使用sprintf时,需要确保目标缓冲区足够大以存储转换后的字符串(包括空终止符\0)。否则,可能会导致缓冲区溢出,这是安全漏洞的常见来源。相比之下,snprintf通过允许你指定目标缓冲区的大小来避免这个问题。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

402

主题

10662

帖子

6

粉丝