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

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

我正在使用嵌入式系统。

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

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

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

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

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

这是一个示例,可以让您开始有用的转换:

 $ cat tc #include  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; uf = 1.234e9; convert(ui); return 0; } $ ./a.out 1252017 * 2 ** 7 + 2 ** 30 

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

 #include 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 = xn; while((n>0)||(i>k)) { if(k == i) k++; *(p+k)='0'+n; x *= 10; n = (int)x; x = xn; 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; } 

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