sprintf(buf,“%。20g”,x)// buf应该有多大? [英] sprintf(buf, "%.20g", x) // how large should buf be?

查看:377
本文介绍了sprintf(buf,“%。20g”,x)// buf应该有多大?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将双值转换为字符串,如下所示:

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



我已将缓冲区大小硬编码为30,但不知道这是否足够大的所有情况。




  • 如何找出我需要的最大缓冲区大小?

  • (因此缓冲区需要增加)从32位切换到64位时?



PS:我不能使用 ostringstream boost :: lexical_cast (请参阅 this

解决方案


我已经硬编码缓冲区大小到30,但不知道这是否足够大,适用于所有情况。


%.20g在尾数中指定20个数字。对小数点加1。 1表示(可能)符号,5表示e + 308或e-308,最坏情况指数。和1为终止null。



20 + 1 + 1 + 5 + 1 = 28.


当从32位切换到64位时,精度是否更高(因此缓冲区需要增加)?


否。



两个架构中的double大小相同。如果你将变量声明为long double,那么你可能在指数e + 4092中还有一个数字,它仍然适合30个字符的缓冲区。



long double是一个过时的80位浮点值,它是486 FPU的本机格式。该FPU架构没有良好地扩展,并且因为被抛弃以支持SSE样式指令,其中最大可能的浮点值是64位双精度。



这是一个很长的说法,30个字符的缓冲区将总是足够的,只要您将打印输出中的尾数限制为20位数即可。


I am converting double values to string like this:

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

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

  • How can I find out the maximum buffer size I need?
  • Does the precision get higher (and therefore buffer needs to increase) when switching from 32bit to 64?

PS: I cannot use ostringstream or boost::lexical_cast for performance reason (see this)

解决方案

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

It is. %.20g specifies 20 digits in the mantissa. add 1 for decimal point. 1 for (possible) sign, 5 for "e+308" or "e-308", the worse case exponent. and 1 for terminating null.

20 + 1 + 1 + 5 + 1 = 28.

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

No.

A double is the same size in both architectures. If you declare your variables as long double, then you possibly have 1 more digit in the exponent "e+4092", which still fits in a 30 character buffer. But only on X86, and only on older processors.

The long double is an obsolete 80 bit form of floating point value that was the native format of the 486 FPU. That FPU architecture didn't scale well and as since been discarded in favor of SSE style instructions where the largest possible floating point value is a 64 bit double.

Which is a long way of saying a buffer of 30 characters will always be sufficient as long as you keep limiting the mantissa in your printout to 20 digits.

这篇关于sprintf(buf,“%。20g”,x)// buf应该有多大?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆