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