如何在不使用C中的sprintf或ftoa的情况下将float / double转换为ASCII?

时间:2010-02-15 20:36:18

标签: c

如何在不使用C中的sprintf或ftoa的情况下将float / double转换为ASCII?

我正在使用嵌入式系统。

3 个答案:

答案 0 :(得分:7)

您采取的方法取决于可能的值范围。您当然对可能的范围有一些内部了解,您可能只对更窄范围内的转换感兴趣。

因此,假设您只对整数值感兴趣。在这种情况下,我只是将数字分配给intlong,此时问题变得相当明显。

或者,假设范围不包括任何大指数,但您对分数的几个数字感兴趣。要获得三位数的分数,我可能会说int x = f * 1000;,转换x,然后将小数点作为字符串操作插入。

如果不能满足以上所有要求,则浮点数或双精度数具有符号位,分数和指数。分数中有一个隐藏的1。 (数字被标准化,直到它们没有前导零,此时它们再做一次移位以获得额外的精度。)然后该数字等于分数(加上前导'1')* 2 **指数。基本上所有使用IEEE 754表示的系统都可以使用this Wikipedia IEEE 754 page来理解格式。 与仅转换整数不同。

对于单精度,一旦得到指数和分数,那么数字的值注1 就是(frac / 2 23 + 1)* 2 exp ,或frac * 2 exp - 23 + 2 exp

以下示例可让您开始有用的转换:

$ cat t.c
#include <stdio.h>

void xconvert(unsigned frac)
{
  if (frac) {
    xconvert(frac / 10);
    printf("%c", frac % 10 | '0');
  }
}

void convert(unsigned i)
{
  unsigned sign, exp, frac;

  sign = i >> 31;
  exp  = (i >> (31 - 8)) - 127;
  frac = i & 0x007fffff;
  if (sign)
    printf("-");
  xconvert(frac);
  printf(" * 2 ** %d + 2 ** %d\n", exp - 23, exp);
  printf("\n");
}

int main(void)
{
  union {
     float f;
     unsigned i;
  } u;

  u.f = 1.234e9;
  convert(u.i);
  return 0;
}
$ ./a.out
1252017 * 2 ** 7 + 2 ** 30

注意1.在这种情况下,分数被转换为好像二进制点在右边而不是左边,然后对指数和隐藏位进行补偿调整。

答案 1 :(得分:1)

#include<stdio.h>
void flot(char* p, float x)
{
  int n,i=0,k=0;
  n=(int)x;
  while(n>0)
  {
    x/=10;
    n=(int)x;
    i++;
 }
 *(p+i) = '.';
 x *= 10;
 n = (int)x;
 x = x-n;
 while((n>0)||(i>k))
 {
   if(k == i)
        k++;
   *(p+k)='0'+n;
   x *= 10;
   n = (int)x;
   x = x-n;
   k++;
 }
 /* Null-terminated string */
 *(p+k) = '\0';
}

int main()
{
  float x;
  char a[20]={};
  char* p=&a;
  printf("Enter the float value.");
  scanf("%f",&x);
  flot(p,x);
  printf("The value=%s",p);
  getchar();
  return 0;
}

答案 2 :(得分:0)

即使在嵌入式系统中,你也很难击败ftoa的表现。为什么重新发明轮子?