#include<stdio.h>
int main()
{
char *nstring = NULL;
int n = 0, i = 0;
double value = 0x1p-1074;
char buf[128] = {0};
n = snprintf(buf, 128,"%.*f", 8, value);
while(i < n) {
printf("buf[%d] : Data [%c]\n", i, buf[i]);
i++;
}
return 0;
}
我在这里使用 snprintf
将 double value
= 0x1p-1074
格式化为 buf
。但是当我执行上面的代码时,我得到:
buf[0] : Data [0]
buf[1] : Data [.]
buf[2] : Data [0]
buf[3] : Data [0]
buf[4] : Data [0]
buf[5] : Data [0]
buf[6] : Data [0]
buf[7] : Data [0]
buf[8] : Data [0]
buf[9] : Data [0]
我尝试使用 glibc 函数 fcvt_r
使用 __snprintf()
如下格式化 0x1p-1074
如下:
n = snprintf (buf, len, "%.*" FLOAT_FMT_FLAG "f", MIN (ndigit, NDIGIT_MAX),
value);
谁能解释一下 FLOAT_FMT_FLAG
的用法?我还尝试在 glib 源 (misc/efgcvt_r.c
) 中用 snprintf()
替换 __snprintf()
并添加一些 printf
;给出了我预期的输出:
buf[0] : Data [4]
buf[1] : Data [.]
buf[2] : Data [9]
buf[3] : Data [4]
buf[4] : Data []
buf[5] : Data []
buf[6] : Data []
buf[7] : Data []
这是预期的输出。我可以在我的测试程序中使用 FLOAT_FMT_FLAG
吗?或者有没有其他方法可以得到与 glibc 源代码相同的输出?
最佳答案
值0x1p-1074
(IEEE-754 binary64 double 的最小可能次正规值,定义为 DBL_TRUE_MIN
中的 <float.h>
)非常接近 0
.使用 %f
打印产生没有指数的小数表示,如果你只需要 8 位小数,它们都将是 0
并且输出符合预期0.00000000
.
你似乎假设 %f
和 fcvt
应该产生相同的数字。仅适用于 1
之间的数字和 10
在幅度上。对于您的示例,fcvt
产生有效数字 4.94
但十进制指数为 -324
.
FLOAT_FMT_FLAG
是一个非标准的 GNU 扩展来告诉 printf
传递的浮点值是 long double
.标准 C 将此标志定义为 L
从 C99 开始。
如果您的目标是生成 fcvt
的输出对于不提供它的 C 库,您可以使用 %.8e
并去掉指数部分。
关于c - 为什么 snprintf 不适用于 double 0x1p-1074 ...?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51761285/