【问题标题】:Get printf to print all float digits获取 printf 以打印所有浮点数
【发布时间】:2015-08-06 16:32:16
【问题描述】:

我对@9​​87654322@ 的行为感到困惑。它打印出3.141593,但M_PI3.14159265358979323846264338327950288。为什么 printf 会这样做,我怎样才能让它打印出整个浮点数。我知道 %1.2f 格式说明符,但如果我使用它们,我会得到一堆未使用的 0,并且输出很难看。我想要浮点数的全部精度,而不是额外的。

【问题讨论】:

  • 一旦将一段文本转换为浮点数或双精度数,“所有”数字就不再是一个有意义的概念。例如,计算机无法知道它转换了“3.14”还是“3.14000000000000000275”,并且它们都恰好产生了相同的内部表示。您只需根据您对所涉及数字精度的了解,选择适合您任务的位数即可。

标签: c printf


【解决方案1】:

为什么 printf 这样做,我怎样才能让它打印出整个 浮动。

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

如果精度缺失,取为6;如果精度是 零且未指定 # 标志,无小数点字符 出现。如果出现小数点字符,至少一位 出现在它面前。 值被四舍五入为适当的数字 位数。

因此调用就相当于:

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

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

printf("%a", M_PI);

输出为:

0x1.921fb54442d18p+1

您可以将其视为“整个浮动”。

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

十进制数字的数量,q,这样任何浮点数与 q 十进制数字可以用p四舍五入为浮点数 基数 b 位并再次返回而不更改 q 小数位

例如:

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

可以打印:

3.14159265358979

【讨论】:

    【解决方案2】:

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

    #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,然后按摩结果。

    【讨论】:

      【解决方案3】:

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

      如果您想打印尽可能多的数字,可能由格式明确表示,浮点数约为 7 位,双精度数约为 15,但这是一个近似值。

      【讨论】:

        猜你喜欢
        • 2017-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-02
        • 2022-10-22
        相关资源
        最近更新 更多