#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
将doublevalue
=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 source(__snprintf()
)中将snprintf()
替换为misc/efgcvt_r.c
,并添加一些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二进制64倍的最小可能次正常值,在DBL_TRUE_MIN
中定义为<float.h>
)非常接近0
。使用%f
打印将生成一个不带指数的十进制表示,如果只需要8个小数位,则它们都将0
并且输出与预期的一样0.00000000
。
你似乎认为%f
和fcvt
应该产生相同的数字。只有数量级在1
和10
之间的数字才是正确的。对于您的示例,fcvt
生成有效数字4.94
,但十进制指数为-324
。FLOAT_FMT_FLAG
是一个非标准GNU扩展,用于告诉printf
传递的浮点值是along double
。标准C将此标志定义为自C99起L
。
如果您的目标是使用不提供fcvt
的C库生成%.8e
的输出,则可以使用并删除指数部分。
关于c - 为什么snprintf不能用于 double 0x1p-1074…?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51761285/