#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
将双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源(__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源代码相同的输出?
答案 0 :(得分:2)
值0x1p-1074
(在DBL_TRUE_MIN
中定义为<float.h>
的IEEE-754 binary64 double的最小可能的正常值)非常接近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
并去除指数部分。