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

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

我正在使用嵌入式系统.

解决方法

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

所以,假设您只对整数值感兴趣.在这种情况下,我只是将数字分配给int或long,此时问题变得相当明显.

或者,假设范围不包括任何大指数,但您对分数的几个数字感兴趣.要获得三位数的分数,我可能会说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.在这种情况下,分数被转换为好像二进制点在右边而不是左边,然后对指数和隐藏位进行补偿调整.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...