获取printf以打印所有浮动数字

时间:2015-08-06 16:32:16

标签: c printf

我对printf("%f", M_PI)的行为感到困惑。它打印出3.141593,但M_PI3.14159265358979323846264338327950288。为什么printf会这样做,如何让它打印出整个浮动。我知道%1.2f格式说明符,但如果我使用它们,那么我得到一堆未使用的0,输出很难看。我想要浮动的整个精度,但不是额外的任何东西。

3 个答案:

答案 0 :(得分:9)

  

为什么printf会这样做,我怎么能让它打印出来呢   浮。

默认情况下,printf()函数对6%f格式说明符的精确度为%F。来自C11(N1570)§7.21.6.1/p8 fprintf函数(强调我的前进):

  

如果缺少精度,将其视为6 ;如果精度是   零,没有指定#flag,没有小数点字符   出现。如果出现小数点字符,则至少有一位数字   出现在它之前。 值四舍五入到适当的数字   数字。

因此,呼叫等同于:

printf("%.6f", M_PI);

这与“整个浮动”完全不同,至少不像你想象的那样直接。 double个对象可能以二进制IEEE-754 double precision表示形式存储。您可以使用%a%A格式说明符查看确切的表示形式,将其打印为十六进制浮点数。例如:

printf("%a", M_PI);

将其输出为:

0x1.921fb54442d18p+1

你可以认为是“整个浮动”。

如果您需要的只是“最长十进制近似值”,那么这是有意义的,然后使用DBL_DIG标题中的<float.h>。 C11 5.2.4.2.2 / p11 C 浮动类型的特征

  

小数位数,q,任何浮点数用   q十进制数字可以用p舍入为浮点数字   基数b数字然后再返回而不更改为q十进制数字

例如:

printf("%.*f", DBL_DIG-1, M_PI);

可以打印:

3.14159265358979

答案 1 :(得分:2)

您可以使用sprintf将浮动字符打印到具有过度显示精度的字符串,然后使用函数修剪0s,然后使用printf将字符串传递给%s以显示它。概念证明:

#include <math.h>
#include <string.h>
#include <stdio.h>

void trim_zeros(char *x){
    int i;
    i = strlen(x)-1;
    while(i > 0 && x[i] == '0') x[i--] = '\0';
}

int main(void){
    char s1[100];
    char s2[100];
    sprintf(s1,"%1.20f",23.01);
    sprintf(s2,"%1.20f",M_PI);
    trim_zeros(s1);
    trim_zeros(s2);
    printf("s1 = %s, s2 = %s\n",s1,s2);
    //vs:
    printf("s1 = %1.20f, s2 = %1.20f\n",23.01,M_PI);
    return 0;
}

输出:

s1 = 23.010000000000002, s2 = 3.1415926535897931
s1 = 23.01000000000000200000, s2 = 3.14159265358979310000

这说明这种方法可能不是你想要的。如果小数部分中的连续零的数量超过一定长度(可以作为参数传递给trim_zeros,您可能希望截断,而不是简单地修剪零。此外 - 您可能希望确保23.0显示23.0而不是23.(所以也许在小数点后保留一个零)。这主要是概念证明 - 如果你不满意printf使用sprintf然后按摩结果。

答案 2 :(得分:1)

将一段文本转换为float或double后,“all”数字不再是有意义的概念。例如,计算机无法知道它转换为“3.14”或“3.14000000000000000275”,并且它们都碰巧产生了相同的浮点数。根据您对所涉及数字精确度的了解,您只需选择适合您任务的位数即可。

如果你想要打印尽可能多的数字,可能会被格式清楚地表示,浮点数约为7位数,双数约为15位数,但这是近似值。