如何使用putchar打印浮点数值?

3

我正在开发一个嵌入式应用程序,需要打印浮点数值。由于空间和其他限制,我只能使用putchar()进行输出。

我正在尝试创建一个函数,该函数以浮点数作为参数,并使用putchar()打印它。我有一个类似的函数,可以用于整数值。

void putLong(long x)
{
    if(x < 0)
    {
        putchar('-');
        x = -x;
    }
    if (x >= 10) 
    {
        putLong(x / 10);
    }
    putchar(x % 10+'0');
}

我该如何为浮点数创建类似的函数?

2
你是否知道在你的嵌入式系统中,浮点数是否遵循IEEE 754标准,或者它们以其他方式表示? - Karl Knechtel
3个回答

2
以下是可能的解决方案:
typedef enum
{
    DEC1 = 10,
    DEC2 = 100,
    DEC3 = 1000,
    DEC4 = 10000,
    DEC5 = 100000,
    DEC6 = 1000000,

} tPrecision ;

void putFloat( float f, tPrecision p )
{
    long i = (long)f ;
    putLong( i ) ;
    f = (f - i) * p ;
    i = abs((long)f) ;
    if( fabs(f) - i >= 0.5f )
    {
        i++ ;
    }
    putchar('.') ;
    putLong( i ) ;
    putchar('\n') ;
}

您将如此使用它:
putFloat( 3.14159f, DEC3 ) ;

该函数将输出“3.142”,请注意第三位数字的四舍五入。

如果您只需要固定数量的小数位,可以省略精度参数并进行硬编码。

使用此函数时,您应该知道浮点数仅具有6个有效数字位数,而不是6个小数位数。因此,如果您尝试使用DEC6打印123.456,则会在第三个位置之后得到错误的数字。忽略第6个有效数字之后的任何数字都应该被忽略,但编写代码以考虑这一点可能在您的应用程序中是不必要的或者在您的约束条件下更加昂贵。


1
你需要什么范围的值和精度/准确性要求?以十进制形式打印浮点数的确切值是一个非常困难的问题,如果你支持80位或128位的long double值,需要大约8kb左右(我可能会有些2的幂次方错误;这是我脑海中的数字)。如果你只支持double,那么你可能只需要1kb左右的工作空间,如果你只想打印较差的近似值,则基本上不需要工作空间。
好的,这是一个非常基本的版本:
void putDouble(double x, int p)
{
    long d;
    if (x<0) {
        putchar('-');
        x=-x;
    }
    d = x;
    putLong(d);
    putchar('.');
    while (p--) {
        x = (x - d) * 10;
        d = x;
        putchar('0'+d);
    }
}

你可能需要修复你的putLong方法,以处理超过2位数的数字,2. :-)


目前我只打印了整数部分,所以任何小数都将是一个改进。 - CodeFusionMobile

0

我认为我的主要方法是将浮点数的整数部分与小数部分分开。

如果您可以使用某种舍入或转换为整数函数,您可以使用putLong方法来输出整数部分。

输出一个小数点。

然后,从浮点数中减去该整数以隔离小数。现在,对于小数,您可以尝试确定小数点后的位数,或者只是乘以任意大的10的幂,然后从结果int的右侧剥离多余的零,并再次应用putLong得到结果。

我怀疑可能有一种更有效或更简单的方法来做到这一点,但我相当确定这种方法可以工作。查找浮点数位用于表示指数和值组件的方式也可能很有用。


这个“有效”的程度取决于您的要求。对于大于整数类型可以存储的最大值的值,它根本不起作用。 - R.. GitHub STOP HELPING ICE
@R:没错,但是你认为将值的小数点前后部分分离的基本概念是有效的吗?即使你需要进行一些额外的内存操作或使用大型数据类型? - DGH
也许吧,但是只需将小数点的位置存储在单独的变量中也可以很好地工作。这真的取决于您使用的方法。 - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接