将double / float转换为字符串

我需要将浮点数转换为十进制(或其他基数)中的等效字符串。 首先需要以xE+0格式进行转换,其中x是浮点数。

我的想法是首先将浮点数截断为临时整数,然后将该整数转换为字符串,然后考虑小数部分,将其乘以10而小数部分不变为0 。 将小数部分转移到小数点的左侧后,再次将整数应用于字符串函数,并将小数部分转换为字符串。 有没有更好的方法,哪个比这更快? 这种方法会引起任何副作用吗?

要将浮点数转换为指数表示,我应该如上所述,然后调整功率吗? 或者直接对IEEE 754浮点表示进行位掩码,并将每个部分转换为字符串。

注意:不能使用其他function,因为我可以访问绝对没有库函数。 这段代码进入玩具内核。

唯一确切的解决方案是对基本转换执行任意精度的十进制算术,因为精确值可能非常长 – 对于80位long double ,最多约10000个小数位。 幸运的是,对于IEEE double来说,它“仅”大约700个左右。

相反,使用单个十进制数字,而不是工作基数为10亿(10位的最高功率适合32位整数),然后将这些“基数为10亿的数字”转换为9位十进制数字在你的计算结束时。

LGPL MIT许可下,我有一个非常密集(相当难读)但有效的实现:

http://git.musl-libc.org/cgit/musl/blob/src/stdio/vfprintf.c?h=v1.1.6

如果你去除所有的六边形浮动支撑,无限/纳米支撑, %g / %f / %e变化支持,四舍五入(如果你只需要精确答案则永远不需要),以及你可能不需要的其他东西,剩下的代码很简单。

使用stdlib.h snprintf() 。 为我工作。

 double num = 123412341234.123456789; char output[50]; snprintf(output, 50, "%f", num); printf("%s", output); 

在一些C库中查看带有"%f"printf()实现。

我知道也许这是不必要的,但我做了一个将float转换为字符串的函数:

码:

 #include  /** Number on countu **/ int n_tu(int number, int count) { int result = 1; while(count-- > 0) result *= number; return result; } /*** Convert float to string ***/ void float_to_string(float f, char r[]) { long long int length, length2, i, number, position, sign; float number2; sign = -1; // -1 == positive number if (f < 0) { sign = '-'; f *= -1; } number2 = f; number = f; length = 0; // Size of decimal part length2 = 0; // Size of tenth /* Calculate length2 tenth part */ while( (number2 - (float)number) != 0.0 && !((number2 - (float)number) < 0.0) ) { number2 = f * (n_tu(10.0, length2 + 1)); number = number2; length2++; } /* Calculate length decimal part */ for (length = (f > 1) ? 0 : 1; f > 1; length++) f /= 10; position = length; length = length + 1 + length2; number = number2; if (sign == '-') { length++; position++; } for (i = length; i >= 0 ; i--) { if (i == (length)) r[i] = '\0'; else if(i == (position)) r[i] = '.'; else if(sign == '-' && i == 0) r[i] = '-'; else { r[i] = (number % 10) + '0'; number /=10; } } } 

用这个:

 void double_to_char(double f,char * buffer){ gcvt(f,10,buffer); } 

查看BSD C标准库是否具有fcvt()。 您可以从源代码开始,而不是从头开始编写代码。 UNIX 98标准fcvt()显然不会输出科学记数法,所以你必须自己实现它,但我认为这并不难。

sprintf可以做到这一点:

 #include  int main() { float w = 234.567; char x[__SIZEOF_FLOAT__]; sprintf(x, "%g", w); puts(x); }