舍入双打 - .5 - sprintf

时间:2009-06-15 06:45:31

标签: c++ rounding printf

我正在使用以下代码舍入到2dp:

sprintf(temp,"%.2f",coef[i]); //coef[i] returns a double

它成功地将6.666舍入到6.67,但在舍入时它无法正常工作 5.555。它返回5.55,而它应该(至少在我看来)返回5.56。

当下一个数字是5时,我怎样才能将它弄圆?即返回5.56。

编辑:我现在意识到这种情况正在发生,因为当我输入带有cin的5.555时 保存为5.554999997。

我将尝试分两个阶段 - 首先是3dp然后是2dp。任何其他 (更优雅)的想法?

5 个答案:

答案 0 :(得分:11)

似乎你必须使用数学轮函数来进行正确的舍入。

printf("%.2f %.2f\n", 5.555, round(5.555 * 100.)/100.);

这会在我的机器上显示以下输出:

5.55 5.56

答案 1 :(得分:11)

数字5.555无法表示为IEEE754中的确切数字。使用5.555打印常量"%.50f"会导致:

5.55499999999999971578290569595992565155029300000000

所以向下舍入。请尝试使用此代码:

printf ("%.2f\n",x+0.0005);

虽然你需要注意可以完全表示的数字,因为它们会被这个表达式错误地舍入。

您需要了解浮点表示的局限性。如果获得准确性很重要,您可以使用(或编码)没有IEEE754表示缺点的BCD或其他十进制类。

答案 2 :(得分:2)

另一种可能的解决方案如何:

printf("%.2f", _nextafter(n, n*2));

这个想法是将数字从零开始增加(n * 2得到正确的符号),浮点数学表示的最小可能数量。

例如:

double n=5.555;
printf("%.2f\n", n);
printf("%.2f\n", _nextafter(n, n*2));
printf("%.20f\n", n);
printf("%.20f\n", _nextafter(n, n*2));

MSVC收益率:

5.55
5.56
5.55499999999999970000
5.55500000000000060000

答案 3 :(得分:1)

这个问题被标记为C ++,所以我将继续这个假设。请注意,与C printf系列不同,C ++流将会循环。您所要做的就是提供您想要的精度,并且流库将为您舍入。我只是把它扔到那里,以防你没有理由不使用流。

答案 4 :(得分:-2)

您也可以这样做(保存乘法/除法):

printf("%.2f\n", coef[i] + 0.00049999);