为什么 snprintf 不适用于 double 0x1p-1074 ...?
Why snprintf is not working for double 0x1p-1074 ...?
#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 的最小可能次正规值,定义为 <float.h>
中的 DBL_TRUE_MIN
)非常接近 0
。使用 %f
打印会产生不带指数的十进制表示,如果您只需要 8 位小数,它们将全部为 0
并且输出符合预期 0.00000000
.
您似乎假设 %f
和 fcvt
应该产生相同的数字。这仅适用于 1
和 10
之间的数字。对于您的示例,fcvt
生成有效数字 4.94
但小数指数为 -324
.
FLOAT_FMT_FLAG
是一个非标准的 GNU 扩展,用于告诉 printf
传递的浮点值是 long double
。自 C99 以来,标准 C 将此标志定义为 L
。
如果您的目标是使用不提供它的 C 库生成 fcvt
的输出,您可以使用 %.8e
并去除指数部分。
#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 的最小可能次正规值,定义为 <float.h>
中的 DBL_TRUE_MIN
)非常接近 0
。使用 %f
打印会产生不带指数的十进制表示,如果您只需要 8 位小数,它们将全部为 0
并且输出符合预期 0.00000000
.
您似乎假设 %f
和 fcvt
应该产生相同的数字。这仅适用于 1
和 10
之间的数字。对于您的示例,fcvt
生成有效数字 4.94
但小数指数为 -324
.
FLOAT_FMT_FLAG
是一个非标准的 GNU 扩展,用于告诉 printf
传递的浮点值是 long double
。自 C99 以来,标准 C 将此标志定义为 L
。
如果您的目标是使用不提供它的 C 库生成 fcvt
的输出,您可以使用 %.8e
并去除指数部分。