问题是静态分配一个足够大的缓冲区以适应打印的双精度格式,格式为%g,最大精度。这似乎是一个足够简单的任务,我遇到了麻烦。我想出的最好的(假设要打印的数字是x)是
char buf[1 + DBL_DIG + DBL_DIG + 1 + 1 + 1 + DBL_DIG + 1];
int len = sprintf(buf, "%.*g", DBL_DIG, x);
DBL_DIG宏来自float.h,显然它应该表示double类型的最大精度。我们需要:
我使用有效位数作为指数中位数的上限。我有任何错误吗?有更好的解决方案吗?我应该只分配64,128或256个字节并希望最好吗?
答案 0 :(得分:5)
使用snprintf()
找出您需要的字符数:
#include <float.h> /* DBL_DIG */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double x = rand() / (double)RAND_MAX;
char find_len[1];
int need_len;
char *buf;
need_len = snprintf(find_len, 1, "%.*g", DBL_DIG, x);
buf = malloc(need_len + 1);
if (buf) {
int used = sprintf(buf, "%.*g", DBL_DIG, x);
printf("need: %d; buf:[%s]; used:%d\n", need_len, buf, used);
free(buf);
}
return 0;
}
您需要 snprintf()
的C99编译器。
snprintf()
由C99标准定义。 C89实现不需要定义snprintf()
,如果它具有扩展名,则不需要按照C99标准的说明“工作”。
答案 1 :(得分:5)
您无法在编译时预先计算大小。 %g格式化程序考虑了区域设置(对于1000的分隔符等) 有关如何安全地计算大小的说明,请参阅http://linux.die.net/man/3/sprintf。
答案 2 :(得分:1)
两件事:%g没有显示所有可表示的数字,%g显示了一个非常适合人类的圆形结果。如果您想要不同的结果,可以使用%f或%e指定精度。
永远不要使用sprintf()而不是使用snprintf()。在你的情况下:
int len = snprintf(buf, dimensionof(buf), "%.*f", DBL_DIG, x);
答案 3 :(得分:1)
您可以使用asprintf
而不是sprintf
。这将分配一个正确大小的缓冲区以适合您的字符串。
答案 4 :(得分:-2)
我应该直接到64,128还是 256并希望最好?
是的,就这样做 - .-