2012-04-26 649 views
5

在UNIX中使用sprintf()double值转换为字符串时,我遇到了一个特定问题。double值的sprintf格式化

比如我有两个值:

double a = 0.009984354523452; 
double b = 0.01; 

虽然转换,我使用:

sprintf(somestringvar, "Double value : %.15f \n", a); 
sprintf(diffstringvar, "Double value : %.15f \n", b); 

转换为字符串。

我的问题是'a',值正确打印,但'b'的值,0的尾部追加。请给我提供任何常用的方法来表示'a'和'b'为准确的值。

+1

我会使用std :: ostringstream这种事情。 – Robinson 2012-04-26 06:21:12

+1

一般来说,不要使用'sprintf()',因为它会导致缓冲区溢出。改为使用'snprintf()',或者Microsoft在Windows上提供的'_s'“安全”版本之一。附:欢迎来到堆栈溢出! – 2012-04-26 06:21:41

+0

嗨,感谢您的早期回应。 ostringstream不是完全精确的。值仅打印为0.009976。我可以使用snprintf(),但问题是在正确打印值时。 – sandy 2012-04-26 07:01:24

回答

8

打印b时会得到零,因为您告诉printf打印15个小数位(%.15f),并且它正在乖乖地这样做。为了获得“确切”的东西,你可能会用简单的%g获得更好的运气。


[基于最近的评论更新]

事情真的取决于你所说的“精确”的东西。如果确切地说,你的意思是“用户最初输入的内容”,那么双倍可能不是你的最佳选择。也许将值存储为字符串,然后在需要在计算中使用它时将其转换为double可能会有效。一旦基于文本的十进制数字转换为双精度数字,它通常不再与文本完全相同。虽然printf()ostream将忠实地打印双精度值(有时它很幸运,它打印的内容看起来与原始值相同),但问题在于双精度本身不再保持实际的原始值。事实上它从来没有。

或者,您可能更喜欢精确的数字实现,而不是像双打那样天生就近似的东西。例如,MySQL有NUMERIC and DECIMAL类型支持完美的精度,代价是强制您提前指定整数和小数位数。这叫做arbitrary precision arithmetic,在C/C++中有这样做的库。

+0

感谢您的回复,我可以理解添加zeoes的逻辑部分。但问题是在运行时我应该从数据库读取值。值可以是任何类型,如上所示,所以我正在寻找打印精确值的一般方法。我尝试了'%g',即使它将值'a'归一化为0.009976 – sandy 2012-04-26 07:05:28

+0

为什么人们会一直投票呢?如果出现问题,请大声说出来,以便我可以改进它,或者提供您自己的替代答案。 – 2013-09-16 00:41:23