Printf 宽度说明符以保持浮点值的精度

Printf width specifier to maintain precision of floating-point value

提问人:Vilhelm Gray 提问时间:5/30/2013 最后编辑:CommunityVilhelm Gray 更新时间:8/21/2023 访问量:377832

问:

是否有宽度说明符可以应用于浮点说明符,该浮点说明符会自动将输出格式化为必要数量的有效数字,以便在重新扫描字符串时获取原始浮点值?printf

例如,假设我将 a 打印为小数点后一位的精度:float2

float foobar = 0.9375;
printf("%.2f", foobar);    // prints out 0.94

当我扫描输出时,我无法保证我会获得原始浮点值(在本例中,我可能不会)。0.940.9375

我想要一种方法,告诉自动将浮点值打印到必要的有效位数,以确保它可以扫描回传递给 的原始值。printfprintf

我可以使用一些宏来派生要传递到的最大宽度,但是是否已经有一个说明符可以自动打印到必要数量的有效数字 - 或者至少打印到最大宽度?float.hprintf

c printf c99 浮点精度

评论

4赞 11/11/2013
@bobobobo 所以你只是建议人们使用一个假设而不是采取便携式方法?
3赞 bobobobo 11/12/2013
@H2CO3 不,我不建议使用“空中假设”,我建议使用已经便携、高效和默认的假设。printf( "%f", val );
2赞 Vilhelm Gray 11/12/2013
@bobobobo 为了将它添加到答案中,您是否能够引用 C99 标准中的条款,该条款规定,如果未指定精度,printf 语句将默认以最大精度输出浮点类型?
2赞 Vilhelm Gray 11/12/2013
@bobobobo我很抱歉,我想你可能误解了这个问题。我感兴趣的是输出的精度(即打印的字符数),而不是数据类型的精度(即浮点数/双精度表示真实值的准确性)。
2赞 chux - Reinstate Monica 11/23/2013
@Vilhelm灰色 C11dr 5.2.4.2.2 “...十进制位数 n 的数目,使得任何具有 p 基数 b 位数的浮点数都可以四舍五入为具有 n 个十进制数字的浮点数,然后再次返回而不更改值,p log10 b b 是 10 ⎡1 + p log10 b⎤ 的幂,否则FLT_DECIMAL_DIG 6 DBL_DECIMAL_DIG 10 LDBL_DECIMAL_DIG 10 ...”6、10、10 是最小值。

答:

12赞 user529758 5/30/2013 #1

只需使用 from 的宏和可变宽度转换说明符 ():<float.h>".*"

float f = 3.14159265358979323846;
printf("%.*f\n", FLT_DIG, f);

评论

3赞 Vilhelm Gray 5/30/2013
@OliCharlesworth 你的意思是这样的:printf("%." FLT_DIG "f\n", f);
4赞 Pascal Cuoq 5/30/2013
+1 但这最适合 ,但不适用于 : 仅当知道要打印的值接近 时。%e%f1.0
4赞 chux - Reinstate Monica 5/31/2013
%e打印非常小的数字的有效数字,并且不打印。 打印(进动完全丧失)。 指纹。%fx = 1e-100%.5f0.00000%.5e1.00000e-100
1赞 11/11/2013
@bobobobo 此外,你错了,因为它“产生了更准确的理由”。 被定义为出于某种原因而定义的值。如果是 6,那是因为 不能容纳超过 6 位的精度。如果使用 打印,则最后一位数字将没有意义。FLT_DIGfloat%.7f
6赞 11/11/2013
@bobobobo 不,不等价,因为并不总是 6。谁在乎效率?I/O 已经非常昂贵了,一位或多或少的精度不会成为瓶颈。%.6fFLT_DIG
26赞 Jens Gustedt 5/30/2013 #2

如果您只对位(resp 十六进制模式)感兴趣,则可以使用该格式。这保证了您:%a

这 如果基数 2 中存在精确表示形式,并且其他表示形式足够大以区分 double 类型的值,则默认精度足以精确表示值。

我必须补充一点,这仅适用于 C99。

119赞 chux - Reinstate Monica 11/11/2013 #3

我推荐@Jens Gustedt 十六进制解决方案:使用 %a。

OP 希望“以最大精度(或至少到最高有效十进制)打印”。

一个简单的例子是打印七分之一,如下所示:

#include <float.h>
int Digs = DECIMAL_DIG;
double OneSeventh = 1.0/7.0;
printf("%.*e\n", Digs, OneSeventh);
// 1.428571428571428492127e-01

但是,让我们更深入地挖掘......

从数学上讲,答案是“0.142857 142857 142857......”,但我们使用的是有限精度的浮点数。 假设 IEEE 754 双精度二进制文件。 因此,结果如下。还显示了前面和后面的可表示浮点数。OneSeventh = 1.0/7.0double

OneSeventh before = 0.1428571428571428 214571170656199683435261249542236328125
OneSeventh        = 0.1428571428571428 49212692681248881854116916656494140625
OneSeventh after  = 0.1428571428571428 769682682968777953647077083587646484375

打印 a 的精确十进制表示形式用途有限。double

C 有 2 个宏系列来帮助我们。
第一组是要以十进制形式打印的字符串的有效位数,因此当向后扫描字符串时, 我们得到原始浮点。显示了 C 规范的最小值和示例 C11 编译器。
<float.h>

FLT_DECIMAL_DIG   6,  9 (float)                           (C11)
DBL_DECIMAL_DIG  10, 17 (double)                          (C11)
LDBL_DECIMAL_DIG 10, 21 (long double)                     (C11)
DECIMAL_DIG      10, 21 (widest supported floating type)  (C99)

第二组是字符串可以扫描成浮点,然后打印 FP,仍然保留相同的字符串表示。显示了 C 规范的最小值和示例 C11 编译器。我相信 C99 之前可用。

FLT_DIG   6, 6 (float)
DBL_DIG  10, 15 (double)
LDBL_DIG 10, 18 (long double)

第一组宏似乎满足了 OP 的有效数字目标。但该并不总是可用的。

#ifdef DBL_DECIMAL_DIG
  #define OP_DBL_Digs (DBL_DECIMAL_DIG)
#else  
  #ifdef DECIMAL_DIG
    #define OP_DBL_Digs (DECIMAL_DIG)
  #else  
    #define OP_DBL_Digs (DBL_DIG + 3)
  #endif
#endif

“+3”是我之前回答的关键。 它的核心是,如果知道往返转换字符串-FP-字符串(设置 #2 宏可用 C89),如何确定 FP-string-FP(设置 #1 宏在 C89 后可用)的数字?通常,加 3 是结果。

现在,要打印多少个有效数字是已知的,并通过 驱动。<float.h>

要打印 N 个有效十进制数字,可以使用各种格式。

对于,精度字段是前导数字和小数点之后的位数。 所以是有序的。注意:这不是在初始"%e"- 1-1int Digs = DECIMAL_DIG;

printf("%.*e\n", OP_DBL_Digs - 1, OneSeventh);
// 1.4285714285714285e-01

对于,精度字段是小数点后的位数。 对于像这样的数字,需要看到所有有效数字。"%f"OneSeventh/1000000.0OP_DBL_Digs + 6

printf("%.*f\n", OP_DBL_Digs    , OneSeventh);
// 0.14285714285714285
printf("%.*f\n", OP_DBL_Digs + 6, OneSeventh/1000000.0);
// 0.00000014285714285714285

注意:许多人习惯于.小数点后显示 6 位数字;6 是默认显示,而不是数字的精度。"%f"

评论

0赞 user1024 7/10/2015
为什么是 1.428571428571428492127e-01 而不是 1.428571428571428492127e-001,'e' 后面的位数应该是 3?
1赞 chux - Reinstate Monica 8/31/2015
@Jingguo 姚明同意参考文献说“精度指定'%f'的小数点字符后面有多少位数字”。那里的“精度”一词不是在数学意义上使用的,而只是用来定义小数点后的位数。1234567890.123,数学上有 13 位精度或有效数字。0.000000000123 具有 3 位数学精度,而不是 13。浮点数是以对数方式分布的。这个答案使用有效数字和数学上的精确感。
1赞 chux - Reinstate Monica 9/22/2015
@Slipp D. Thompson “显示了 C 规范的最小值和示例 C11 编译器。
1赞 Slipp D. Thompson 9/22/2015
@chux啊,我在文章中错过了这种相关性。干杯。
1赞 Greg A. Woods 3/27/2016
事实上,你是对的——我的技巧只对大小介于 1.0 和 1.0eDBL_DIG 之间的值有效,这可以说是唯一真正适合打印的范围。正如你所展示的那样,使用当然是一种更好的方法,也是一个有效的体面的答案(尽管它可能不如使用(如果它可用,当然应该DBL_DECIMAL_DIG可用)。我一直希望有一个格式说明符,它总是四舍五入到最大精度(而不是硬编码的小数点后 6 位)。"%f""%e""%a""%a"
24赞 bobobobo 11/18/2013 #4

不,没有这样的 printf 宽度说明符可以以最大精度打印浮点。让我解释一下原因。

and 的最大精度是可变的,并且取决于 or 的实际floatdoublefloatdouble

召回并以 sign.exponent.mantissa 格式存储。这意味着用于小数的小数分量比用于大数的位数多得多floatdouble

enter image description here

例如,可以很容易地区分 0.0 和 0.1。float

float r = 0;
printf( "%.6f\n", r ) ; // 0.000000
r+=0.1 ;
printf( "%.6f\n", r ) ; // 0.100000

但不知道 和 之间的区别。float1e271e27 + 0.1

r = 1e27;
printf( "%.6f\n", r ) ; // 999999988484154753734934528.000000
r+=0.1 ;
printf( "%.6f\n", r ) ; // still 999999988484154753734934528.000000

这是因为所有精度(受尾数位数的限制)都用完了大部分数字,即小数点后剩下的大部分。

修饰符只是表示要从浮点数打印多少个十进制值,就格式而言可用的精度取决于数字的大小,这一事实取决于您作为程序员来处理。 不能/不能为您处理。%.fprintf

评论

2赞 Vilhelm Gray 11/19/2013
这很好地解释了将浮点值精确打印到特定小数位的局限性。但是,我认为我最初选择的词语过于模棱两可,因此我更新了我的问题,以避免使用“最大精度”一词,希望它可以消除混淆。
0赞 bobobobo 11/19/2013
这仍然取决于您正在打印的数字的值。
3赞 12/23/2013
这在一定程度上是正确的,但它没有回答问题,你对 OP 在问什么感到困惑。他问是否可以查询 a 提供的有效 [十进制] 数字的数量,而你断言没有这样的东西(即没有),这是错误的。floatFLT_DIG
1赞 Don Hatch 9/24/2016
您是否假设格式字母必须是“f”?我不认为这是必需的。我对这个问题的理解是,OP 正在寻找一些产生无损往返的 printf 格式说明符,所以 @ccxvii 的答案(“%.9g”表示浮点数,“%.17g”表示双精度)是一个很好的答案。也许从中删除“宽度”一词会更好地表达这个问题。
1赞 sleep 6/10/2019
这不是问题要问的。
105赞 ccxvii 1/16/2014 #5

无损打印浮点数的简短答案(以便可以读取它们 回到完全相同的数字,除了 NaN 和 Infinity):

  • 如果类型为 float:请使用 .printf("%.9g", number)
  • 如果类型为 double:请使用 .printf("%.17g", number)

不要使用 ,因为这仅指定小数点后有多少位有效数字,并且会截断小数字。作为参考,可以在其中找到幻数 9 和 17 定义和 。%ffloat.hFLT_DECIMAL_DIGDBL_DECIMAL_DIG

评论

9赞 Vilhelm Gray 1/16/2014
你能解释说明符吗?%g
19赞 ccxvii 1/17/2014
%g 根据精度要求打印具有任意位数的数字,当数字较小或较大时,首选指数语法(1e-5 而不是 .00005),并跳过任何尾随零(1 而不是 1.00000)。
1赞 truthseeker 11/21/2014
double 值的尾数长度为 53 位(1 位是隐式的)。因此,双精度值的精度为 53 / log2(10) = 15.95 位小数。因此,如果您想明确地以十进制格式表示 IEEE 754 数字,您至少需要 ceil(53 / log2(10)) = 16 位小数。在我的程序中,我使用了 17 位小数来确保。不知道哪个值是正确的 16 或 17。但15个名额肯定是不够的。
5赞 Don Hatch 6/14/2016
@chux - 你对 %.16g 的行为有误;对于区分 1.000_0000_0000_0000_2e-01 和 1.000_0000_0000_0000_3e-01 的示例来说,这是不够的。需要%.17g。
1赞 Don Hatch 9/24/2016
顺便说一句,这里有一些很好的参考资料来解释和推导 9 和 17:en.cppreference.com/w/cpp/types/numeric_limits/max_digits10 open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2005.pdf
6赞 Greg A. Woods 7/18/2016 #6

在我对一个答案的评论中,我感叹说,我一直想要某种方法以十进制形式以浮点值打印所有有效数字,就像问题问的那样。好吧,我终于坐下来写了它。它不是很完美,这是打印附加信息的演示代码,但它主要适用于我的测试。如果您(即任何人)想要驱动它进行测试的整个包装程序的副本,请告诉我。

static unsigned int
ilog10(uintmax_t v);

/*
 * Note:  As presented this demo code prints a whole line including information
 * about how the form was arrived with, as well as in certain cases a couple of
 * interesting details about the number, such as the number of decimal places,
 * and possibley the magnitude of the value and the number of significant
 * digits.
 */
void
print_decimal(double d)
{
        size_t sigdig;
        int dplaces;
        double flintmax;

        /*
         * If we really want to see a plain decimal presentation with all of
         * the possible significant digits of precision for a floating point
         * number, then we must calculate the correct number of decimal places
         * to show with "%.*f" as follows.
         *
         * This is in lieu of always using either full on scientific notation
         * with "%e" (where the presentation is always in decimal format so we
         * can directly print the maximum number of significant digits
         * supported by the representation, taking into acount the one digit
         * represented by by the leading digit)
         *
         *        printf("%1.*e", DBL_DECIMAL_DIG - 1, d)
         *
         * or using the built-in human-friendly formatting with "%g" (where a
         * '*' parameter is used as the number of significant digits to print
         * and so we can just print exactly the maximum number supported by the
         * representation)
         *
         *         printf("%.*g", DBL_DECIMAL_DIG, d)
         *
         *
         * N.B.:  If we want the printed result to again survive a round-trip
         * conversion to binary and back, and to be rounded to a human-friendly
         * number, then we can only print DBL_DIG significant digits (instead
         * of the larger DBL_DECIMAL_DIG digits).
         *
         * Note:  "flintmax" here refers to the largest consecutive integer
         * that can be safely stored in a floating point variable without
         * losing precision.
         */
#ifdef PRINT_ROUND_TRIP_SAFE
# ifdef DBL_DIG
        sigdig = DBL_DIG;
# else
        sigdig = ilog10(uipow(FLT_RADIX, DBL_MANT_DIG - 1));
# endif
#else
# ifdef DBL_DECIMAL_DIG
        sigdig = DBL_DECIMAL_DIG;
# else
        sigdig = (size_t) lrint(ceil(DBL_MANT_DIG * log10((double) FLT_RADIX))) + 1;
# endif
#endif
        flintmax = pow((double) FLT_RADIX, (double) DBL_MANT_DIG); /* xxx use uipow() */
        if (d == 0.0) {
                printf("z = %.*s\n", (int) sigdig + 1, "0.000000000000000000000"); /* 21 */
        } else if (fabs(d) >= 0.1 &&
                   fabs(d) <= flintmax) {
                dplaces = (int) (sigdig - (size_t) lrint(ceil(log10(ceil(fabs(d))))));
                if (dplaces < 0) {
                        /* XXX this is likely never less than -1 */
                        /*
                         * XXX the last digit is not significant!!! XXX
                         *
                         * This should also be printed with sprintf() and edited...
                         */
                        printf("R = %.0f [%d too many significant digits!!!, zero decimal places]\n", d, abs(dplaces));
                } else if (dplaces == 0) {
                        /*
                         * The decimal fraction here is not significant and
                         * should always be zero  (XXX I've never seen this)
                         */
                        printf("R = %.0f [zero decimal places]\n", d);
                } else {
                        if (fabs(d) == 1.0) {
                                /*
                                 * This is a special case where the calculation
                                 * is off by one because log10(1.0) is 0, but
                                 * we still have the leading '1' whole digit to
                                 * count as a significant digit.
                                 */
#if 0
                                printf("ceil(1.0) = %f, log10(ceil(1.0)) = %f, ceil(log10(ceil(1.0))) = %f\n",
                                       ceil(fabs(d)), log10(ceil(fabs(d))), ceil(log10(ceil(fabs(d)))));
#endif
                                dplaces--;
                        }
                        /* this is really the "useful" range of %f */
                        printf("r = %.*f [%d decimal places]\n", dplaces, d, dplaces);
                }
        } else {
                if (fabs(d) < 1.0) {
                        int lz;

                        lz = abs((int) lrint(floor(log10(fabs(d)))));
                        /* i.e. add # of leading zeros to the precision */
                        dplaces = (int) sigdig - 1 + lz;
                        printf("f = %.*f [%d decimal places]\n", dplaces, d, dplaces);
                } else {                /* d > flintmax */
                        size_t n;
                        size_t i;
                        char *df;

                        /*
                         * hmmmm...  the easy way to suppress the "invalid",
                         * i.e. non-significant digits is to do a string
                         * replacement of all dgits after the first
                         * DBL_DECIMAL_DIG to convert them to zeros, and to
                         * round the least significant digit.
                         */
                        df = malloc((size_t) 1);
                        n = (size_t) snprintf(df, (size_t) 1, "%.1f", d);
                        n++;                /* for the NUL */
                        df = realloc(df, n);
                        (void) snprintf(df, n, "%.1f", d);
                        if ((n - 2) > sigdig) {
                                /*
                                 * XXX rounding the integer part here is "hard"
                                 * -- we would have to convert the digits up to
                                 * this point back into a binary format and
                                 * round that value appropriately in order to
                                 * do it correctly.
                                 */
                                if (df[sigdig] >= '5' && df[sigdig] <= '9') {
                                        if (df[sigdig - 1] == '9') {
                                                /*
                                                 * xxx fixing this is left as
                                                 * an exercise to the reader!
                                                 */
                                                printf("F = *** failed to round integer part at the least significant digit!!! ***\n");
                                                free(df);
                                                return;
                                        } else {
                                                df[sigdig - 1]++;
                                        }
                                }
                                for (i = sigdig; df[i] != '.'; i++) {
                                        df[i] = '0';
                                }
                        } else {
                                i = n - 1; /* less the NUL */
                                if (isnan(d) || isinf(d)) {
                                        sigdig = 0; /* "nan" or "inf" */
                                }
                        }
                        printf("F = %.*s. [0 decimal places, %lu digits, %lu digits significant]\n",
                               (int) i, df, (unsigned long int) i, (unsigned long int) sigdig);
                        free(df);
                }
        }

        return;
}


static unsigned int
msb(uintmax_t v)
{
        unsigned int mb = 0;

        while (v >>= 1) { /* unroll for more speed...  (see ilog2()) */
                mb++;
        }

        return mb;
}

static unsigned int
ilog10(uintmax_t v)
{
        unsigned int r;
        static unsigned long long int const PowersOf10[] =
                { 1LLU, 10LLU, 100LLU, 1000LLU, 10000LLU, 100000LLU, 1000000LLU,
                  10000000LLU, 100000000LLU, 1000000000LLU, 10000000000LLU,
                  100000000000LLU, 1000000000000LLU, 10000000000000LLU,
                  100000000000000LLU, 1000000000000000LLU, 10000000000000000LLU,
                  100000000000000000LLU, 1000000000000000000LLU,
                  10000000000000000000LLU };

        if (!v) {
                return ~0U;
        }
        /*
         * By the relationship "log10(v) = log2(v) / log2(10)", we need to
         * multiply "log2(v)" by "1 / log2(10)", which is approximately
         * 1233/4096, or (1233, followed by a right shift of 12).
         *
         * Finally, since the result is only an approximation that may be off
         * by one, the exact value is found by subtracting "v < PowersOf10[r]"
         * from the result.
         */
        r = ((msb(v) * 1233) >> 12) + 1;

        return r - (v < PowersOf10[r]);
}

评论

0赞 Pryftan 10/15/2019
我不在乎它是否回答了这个问题——这真的令人印象深刻。这需要经过一些思考,应该得到承认和赞扬。如果你以某种方式(无论是在这里还是其他地方)包含完整的测试代码,也许会很好,但即使没有它,这确实是一项好工作。为此获得+1!
0赞 chux - Reinstate Monica 4/5/2022
@GregA.Woods Code 确实存在负数问题,因为最后一位数字相差 1。也许使用 a(添加空格)来固定缓冲区长度,无论是 + 还是 -。snprintf(df, n, "% .1f", d);
0赞 Greg A. Woods 4/6/2022
啊,是的,负数。感谢您的评论!我会在原始资料中做一个笔记,并在我有空闲时间时尝试改进它。
6赞 Diomidis Spinellis 12/27/2018 #7

我运行了一个小实验来验证打印确实完全保留了数字的二进制表示。事实证明,对于我尝试过的编译器和 C 库来说,确实是所需的位数,即使少一位数字进行打印也会造成一个重大问题。DBL_DECIMAL_DIGDBL_DECIMAL_DIG

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

union {
    short s[4];
    double d;
} u;

void
test(int digits)
{
    int i, j;
    char buff[40];
    double d2;
    int n, num_equal, bin_equal;

    srand(17);
    n = num_equal = bin_equal = 0;
    for (i = 0; i < 1000000; i++) {
        for (j = 0; j < 4; j++)
            u.s[j] = (rand() << 8) ^ rand();
        if (isnan(u.d))
            continue;
        n++;
        sprintf(buff, "%.*g", digits, u.d);
        sscanf(buff, "%lg", &d2);
        if (u.d == d2)
            num_equal++;
        if (memcmp(&u.d, &d2, sizeof(double)) == 0)
            bin_equal++;
    }
    printf("Tested %d values with %d digits: %d found numericaly equal, %d found binary equal\n", n, digits, num_equal, bin_equal);
}

int
main()
{
    test(DBL_DECIMAL_DIG);
    test(DBL_DECIMAL_DIG - 1);
    return 0;
}

我使用 Microsoft 的 C 编译器 19.00.24215.1 和 gcc 版本 7.4.0 20170516 (Debian 6.3.0-18+deb9u1) 运行它。少使用一位十进制数字会使比较完全相等的数字数量减半。(我还验证了使用时确实会产生大约一百万个不同的数字。以下是详细结果。rand()

Microsoft C

Tested 999507 values with 17 digits: 999507 found numericaly equal, 999507 found binary equal
Tested 999507 values with 16 digits: 545389 found numericaly equal, 545389 found binary equal

海湾合作委员会

Tested 999485 values with 17 digits: 999485 found numericaly equal, 999485 found binary equal
Tested 999485 values with 16 digits: 545402 found numericaly equal, 545402 found binary equal

评论

1赞 chux - Reinstate Monica 3/4/2020
“使用 Microsoft 的 C 编译器运行它” --> 该编译器可能有 .考虑或类似操作,以确保所有位都有机会为 0 或 1。RAND_MAX == 32767u.s[j] = (rand() << 8) ^ rand();
0赞 Diomidis Spinellis 3/5/2020
事实上,它的RAND_MAX是 32767,所以你的建议是正确的。
1赞 Diomidis Spinellis 3/5/2020
我更新了帖子以按照 @chux-ReinstateMonica 的建议处理RAND_MAX。结果与之前获得的结果相似。
6赞 Stéphane Mottelet 9/18/2019 #8

据我所知,有一种扩散良好的算法允许输出到必要数量的有效数字,这样当扫描回字符串时,原始浮点值是由 David Gay 编写的,可以在 Netlib 上找到(另见相关论文)。例如,在 Python、MySQL、Scilab 等中使用此代码。dtoa.c

评论

0赞 Mark VY 9/18/2021
大卫·盖伊,而不是丹尼尔·盖伊。(具体来说,David M. Gay。不知道 M 代表什么。
0赞 user1387 5/31/2023 #9

为了补充 Stéphane 的答案,最先进的算法被称为“Dragon4”和“Grisu”。

在自己研究这个问题时,我发现这篇文章包含背景信息、相关论文的链接和实现:

https://www.ryanjuckett.com/printing-floating-point-numbers/

-1赞 Kip Knight 12/21/2023 #10

您需要额外的信息,即值的不确定性。 0.9375 +/- 0.005

float v=0.9275;
float dv=0.005;
int base=10;
int sigfigs=ceil(-log10(dv)/log10(base))-ceil(-log10(v)/log10(base));

评论

0赞 ad absurdum 12/21/2023
我不明白这如何回答 OP 问题。OP 希望以这样一种方式打印浮点数,以便可以读取(可能由 )读取打印的表示以恢复原始浮点数。sscanf