2010-12-05 89 views
3

我正在研究一个嵌入式应用程序,需要打印浮点值。由于空间和其他限制,我只能使用putchar()输出。如何使用putchar打印浮点值?

我想创建一个函数,它将float作为参数并使用putchar()打印出来。我有一个类似的函数可用于整数值。

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

我怎么能做一个类似的浮动功能?

+2

你碰巧知道浮动是否遵循嵌入式系统上的IEEE 754标准,或者它们是否以其他方式表示? – 2010-12-05 03:44:06

回答

0

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

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

输出一个小数点。

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

我怀疑可能有更高效或更简单的方法来做到这一点,但我很肯定这种方法可行。查找浮点数用于表示指数和值的组件也可能有用。

+0

这个“工作”的程度很大程度上取决于您的要求。对于大于整数类型可以存储的最大值的值,它根本无法工作。 – 2010-12-05 03:40:38

+0

@R:这是真的,但是,你会说,分离值的前后小数部分的基本概念是有效的,即使你必须做一些额外的内存操作或使用大型数据类型? – DGH 2010-12-05 03:44:25

1

你需要什么样的数值范围和精度/精度要求?以十进制打印浮点数的确切值是一个非常困难的问题,如果你需要高达8 kb左右的工作空间(我可能会失去2个幂的权力;这是我的头顶)支持80位或128位long double值。如果你只支持double,你可能会得到1 kb左右,如果你只是想打印不好的近似值,基本上没有工作空间。

OK,所以这里是一个非常基本的版本:

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 :-)

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位有效数字后的任何数字,但编写代码时考虑到这一点,在您的应用程序中可能是不必要的,或者您希望给出的约束条件更贵。