其他分享
首页 > 其他分享> > c – sprintf(buf,“%.20g”,x)//应该有多大?

c – sprintf(buf,“%.20g”,x)//应该有多大?

作者:互联网

我正在将double值转换为字符串,如下所示:

std::string conv(double x) {
    char buf[30];
    sprintf(buf, "%.20g", x);
    return buf;
}

我已经将缓冲区大小硬编码为30,但我不确定它是否足够大以适应所有情况.

>如何找到我需要的最大缓冲区大小?
>从32位切换到64时,精度是否会提高(因此缓冲区需要增加)?

PS:出于性能原因,我不能使用ostringstream或boost :: lexical_cast(参见this)

解决方法:

I have hardcoded the buffer size to 30, but am not sure if this is large enough for all cases.

它是. %.20g指定尾数中的20位数.为小数点加1. 1表示(可能)符号,5表示“e 308”或“e-308”,最差情况指数.和1表示终止null.

20 1 1 5 1 = 28.

Does the precision get higher (and therefore buffer needs to increase) when switching from 32bit to 64?

没有.

两种体系结构中的双倍大小相同.如果将变量声明为long double,那么在指数“e 4092”中可能还有1个数字,它仍然适合30个字符的缓冲区.但仅限于X86,仅适用于较旧的处理器.

long double是一种过时的80位浮点值形式,它是486 FPU的原生格式. FPU体系结构不能很好地扩展,因为已经丢弃了有利于SSE样式指令,其中最大可能浮点值是64位双精度.

只要您将打印输出中的尾数限制为20位,只要说30个字符的缓冲区就足够了.

标签:buffer-overflow,c,printf,floating-point,floating-accuracy
来源: https://codeday.me/bug/20190724/1519340.html