10

我正在使用以下代码舍入到 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。还有其他(更优雅)的想法吗?

4

5 回答 5

13

看来您必须使用数学舍入函数才能正确舍入。

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

这在我的机器上给出了以下输出:

5.55 5.56
于 2009-06-15T06:52:53.080 回答
11

该数字5.555在 IEEE754 中不能表示为确切的数字。打印出常数5.555"%.50f"结果为:

5.55499999999999971578290569595992565155029300000000

所以它被四舍五入。尝试改用这个:

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

尽管您需要小心可以精确表示的数字,因为它们会被此表达式错误地四舍五入。

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

于 2009-06-15T06:56:00.127 回答
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
于 2009-06-24T04:03:49.357 回答
1

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

于 2009-06-15T13:34:27.717 回答
-2

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

printf("%.2f\n", coef[i] + 0.00049999);
于 2009-06-15T06:59:07.043 回答