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

标签 c

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

我正在使用嵌入式系统。

最佳答案

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

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

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

如果没有上述所有条件, float 或 double 有一个符号位、一个分数和一个指数。分数中有一个隐藏的 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 - 如何在不使用 C 中的 sprintf 或 ftoa 的情况下将 float/double 转换为 ASCII?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2268725/

相关文章:

c# - Server A(C#)与B(C)通信解决方案

c - 随机生成的数字不能与 while 循环一起正常工作

c - 在 OSX 上干预,我的函数没有被调用

c - #include C 中数组语法库?

线条的颜色没有变化?

c - 在不同的线程中创建了多少个静态变量/函数的副本?

c - IPv6 绑定(bind)失败

c - 无论如何,VLA 的意义何在?

c - 在 Cygwin 下用 C 打印彩色文本

C 对传入字符串的字符串操作