C语言 将双精度/浮点数转换为字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7228438/
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
Convert double/float to string
提问by phoxis
I need to convert a floating point number to an equivalent string in decimal (or other base). Conversion at first needs to be done in the format xE+0where xis the floating point number.
我需要将浮点数转换为十进制(或其他基数)的等效字符串。转换在首先需要在格式来进行xE+0,其中x是浮点数。
The idea I have is to first truncate the floating point number into a temporary integer and then convert that integer into string, and then consider the fractional part, multiply it with 10while the fractional part does not become 0. After the fractional part is transferred into the left side of the decimal point, apply the integer to string function again and convert the fraction part to string. Is there a better way, which will be faster than this? Will this method induce any kind of side effects?
我的想法是首先将浮点数截断为临时整数,然后将该整数转换为字符串,然后考虑小数部分,将其与小数部分相乘10而小数部分不会变成0。小数部分转入小数点左侧后,再次将整数应用于字符串函数,将小数部分转换为字符串。有没有比这更快的更好的方法?这种方法会引起任何副作用吗?
To convert the floating point number into exponential representation shall I do the same as above and then adjust the power? Or directly bitmask the IEEE 754floating point representation and convert each part into string.
要将浮点数转换为指数表示,我应该像上面一样做然后调整幂吗?或者直接对IEEE 754浮点表示进行位掩码并将每个部分转换为字符串。
Note: No other functions could be used, because I have access to absolutely no library functions. This code goes into a toy kernel.
注意:不能使用其他函数,因为我绝对不能访问库函数。此代码进入玩具内核。
采纳答案by R.. GitHub STOP HELPING ICE
The only exact solution is to perform arbitrary-precision decimal arithmetic for the base conversion, since the exact value can be verylong - for 80-bit long double, up to about 10000 decimal places. Fortunately it's "only" up to about 700 places or so for IEEE double.
唯一精确的解决方案是对基数转换执行任意精度的十进制算术,因为精确值可能很长 - 对于 80 位long double,最多约 10000 个小数位。幸运的是,对于 IEEE 来说,它“仅”最多大约 700 个位置double。
Rather than working with individual decimal digits, it's helpful to instead work base-1-billion (the highest power of 10 that fits in a 32-bit integer) and then convert these "base-1-billion digits" to 9 decimal digits each at the end of your computation.
不是使用单个十进制数字,而是使用以 10 亿为基数(适合 32 位整数的 10 的最高幂)然后将这些“以 10 亿为基数的数字”转换为 9 个十进制数字会很有帮助在你的计算结束时。
I have a very dense (rather hard to read) but efficient implementation here, under LGPLMIT license:
在LGPLMIT 许可下,我在这里有一个非常密集(相当难以阅读)但有效的实现:
http://git.musl-libc.org/cgit/musl/blob/src/stdio/vfprintf.c?h=v1.1.6
http://git.musl-libc.org/cgit/musl/blob/src/stdio/vfprintf.c?h=v1.1.6
If you strip out all the hex float support, infinity/nan support, %g/%f/%evariation support, rounding (which will never be needed if you only want exact answers), and other things you might not need, the remaining code is rather simple.
如果去掉所有的十六进制浮点支持,无限/楠的支持,%g/ %f/%e变异的支持,倒圆(这将永远不会被需要,如果你只想要确切的答案),你可能不需要其他的东西,剩下的代码是相当简单的。
回答by sujeeth.mr
Use snprintf()from stdlib.h. Worked for me.
snprintf()从使用stdlib.h。对我来说有效。
double num = 123412341234.123456789;
char output[50];
snprintf(output, 50, "%f", num);
printf("%s", output);
回答by wormsparty
Go and look at the printf()implementation with "%f"in some C library.
去看看在一些 C 库中的printf()实现"%f"。
回答by JJJakubJJ
I know maybe it is unnecessary, but I made a function which converts float to string:
我知道这可能是不必要的,但我做了一个将浮点数转换为字符串的函数:
CODE:
代码:
#include <stdio.h>
/** 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] = 'void double_to_char(double f,char * buffer){
gcvt(f,10,buffer);
}
';
else if(i == (position))
r[i] = '.';
else if(sign == '-' && i == 0)
r[i] = '-';
else
{
r[i] = (number % 10) + '0';
number /=10;
}
}
}
回答by Ingo
Use this:
用这个:
#include <stdio.h>
int main() {
float w = 234.567;
char x[__SIZEOF_FLOAT__];
sprintf(x, "%g", w);
puts(x);
}
回答by Mike Crawford
See if the BSD C Standard Library has fcvt(). You could start with the source for it that rather than writing your code from scratch. The UNIX 98 standard fcvt() apparently does not output scientific notation so you would have to implement it yourself, but I don't think it would be hard.
查看 BSD C 标准库是否有 fcvt()。您可以从源代码开始,而不是从头开始编写代码。UNIX 98 标准 fcvt() 显然不输出科学记数法,因此您必须自己实现它,但我认为这并不难。
回答by Mike Crawford
sprintfcan do this:
sprintf可以做到这一点:
##代码##
