【问题标题】:How can I convert a float/double to ASCII without using sprintf or ftoa in C?如何在不使用 C 中的 sprintf 或 ftoa 的情况下将 float/double 转换为 ASCII?
【发布时间】:2018-06-21 17:50:36
【问题描述】:

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

我正在使用嵌入式系统。

【问题讨论】:

  • 您自己实现ftoa。如果您需要一些灵感,请查看开源标准库中的实现。
  • 您可以访问“math.h”吗?
  • 如果哈利波特不可用,并且精度很重要,请致电通灵师。否则,请看这里:edaboard.com/ftopic41714.html

标签: c


【解决方案1】:

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

所以,假设您只对整数值感兴趣。在这种情况下,我只需将号码分配给intlong,此时问题就变得相当明显了。

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

如果上述所有条件都失败了,浮点数或双精度数就会有一个符号位、一个分数和一个指数。分数中有一个隐藏的1。 (数字被归一化,直到它们没有前导零,此时它们再进行一次移位以获得额外的精度。)然后该数字等于分数(加上前导“1”)* 2 ** 指数.基本上所有系统都使用 IEEE 754 表示,您只需使用 this Wikipedia IEEE 754 page 即可了解格式。 与仅仅转换一个整数并没有什么不同。

对于单精度,一旦得到指数和分数,则该数字的值注1为 (frac / 223 + 1) * 2exp,或 frac * 2exp - 23 + 2exp

这是一个可以帮助您开始进行有用转换的示例:

$ 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. 在这种情况下,分数被转换为好像二进制点在右侧而不是左侧,然后对指数和隐藏位进行补偿调整。

【讨论】:

    【解决方案2】:
    #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;
    }
    

    【讨论】:

      【解决方案3】:

      即使在嵌入式系统中,您也很难超越 ftoa 的性能。为什么要重新发明轮子?

      【讨论】:

      • ftoa 在提供的库中可能实际上不可用。毕竟,它不是标准库的一部分,即使是,嵌入式系统也经常使用省略大部分标准库的独立实现。
      猜你喜欢
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      相关资源
      最近更新 更多