C语言 如何在不使用 C 中的 sprintf 或 ftoa 的情况下将浮点/双精度转换为 ASCII?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2268725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:29:49  来源:igfitidea点击:

How can I convert a float/double to ASCII without using sprintf or ftoa in C?

c

提问by patrick

How can I convert a float/double to ASCII without using sprintf or ftoa in C?

如何在不使用 C 中的 sprintf 或 ftoa 的情况下将浮点/双精度转换为 ASCII?

I am using an embedded system.

我正在使用嵌入式系统。

回答by DigitalRoss

The approach you take will depend on the possible range of values. You certainly have some internal knowledge of the possible range, and you may only be interested in conversions within a more narrow range.

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

So, suppose you are only interested in the integer value. In this case, I would just assign the number to an intor long, at which point the problem becomes fairly obvious.

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

Or, suppose the range won't include any large exponents but you are interested in several digits of fraction. To get three digits of fraction, I might say int x = f * 1000;, convert x, and then insert the decimal point as a string operation.

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

Failing all of the above, a float or double has a sign bit, a fraction, and an exponent. There is a hidden 1in the fraction. (The numbers are normalized until they have no leading zeroes, at which point they do one more shift to gain an extra bit of precision.) The number is then equal to the fraction (plus a leading '1') * 2 ** exponent. With essentially all systems using the IEEE 754 representation you can just use this Wikipedia IEEE 754 pageto understand the format. It's not thatdifferent from just converting an integer.

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

For single precision, once you get the exponent and fraction, the valueNote 1of the number is then (frac / 223+ 1) * 2exp, or frac * 2exp - 23+ 2exp.

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

Here is an example that should get you started on a useful conversion:

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

$ 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


Note 1. In this case the fraction is being converted as if the binary point was on the right instead of the left, with compensating adjustments then made to the exponent and hidden bit.

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

回答by Viswesn

#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) = '##代码##';
}

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;
}

回答by Joel

Even in an embedded system, you'd be hard pressed to beat the performance of ftoa. Why reinvent the wheel?

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