[编辑] OP 澄清只有打印的值需要四舍五入到小数点后 2 位。
OP 观察到,每“舍入到偶数”或“从零舍入”的数字“中途”舍入是误导性的。在 0.005、0.015、0.025、... 0.995 等 100 个“中途”数字中,通常只有 4 个恰好是“中途”:0.125、0.375、0.625、0.875。这是因为浮点数格式使用 base-2 并且无法精确表示 2.565 之类的数字。
取而代之的是,像这样的样本数是假设binary642.565
的最接近的double
值 。将该数字四舍五入到最接近的 0.01 应该是 2.56 而不是 OP 所希望的 2.57。2.564999999999999947...
因此,只有以 0.125 和 0.625 结尾的数字恰好位于中间区域并向下舍入,而不是 OP 所希望的向上舍入。建议接受并使用:
printf("%.2lf",variable); // This should be sufficient
为了接近 OP 的目标,可以 A)针对以 0.125 或 0.625 结尾的数字进行测试,或者 B)略微增加。最小的增加将是
#include <math.h>
printf("%.2f", nextafter(x, 2*x));
使用@Clifford 可以找到另一种轻推方法。
double
[将 a 舍入到最接近double
的 0.01 倍数的前答案]
典型的浮点使用像binary64这样的格式,它采用 base-2。“四舍五入到最接近的数学 0.01 并远离 0.0”具有挑战性。
正如@Pascal Cuoq 提到的那样,浮点数2.555
通常只是接近2.555
并且具有更精确的值,例如不是2.555000000000000159872...
一半。
下面的@BLUEPIXY 解决方案是最好的和实用的。
x = round(100.0*x)/100.0;
“舍入函数将其参数舍入为浮点格式的最接近的整数值,从零开始舍入一半情况,而不管当前舍入方向如何。” C11dr §7.12.9.6。
该((int)(100 * (x + 0.005)) / 100.0)
方法有两个问题:对于负数(OP 未指定),它可能会朝错误的方向舍入,并且整数通常具有更小的范围(INT_MIN
到INT_MAX
)double
。
仍然有一些情况,当double x = atof("1.115");
它最终接近 1.12 时,它真的应该是1.11
因为1.115
, as adouble
真的更接近1.11
而不是“中途”。
string x rounded x
1.115 1.1149999999999999911182e+00 1.1200000000000001065814e+00
OP 没有指定负数的舍入,假设y = -f(-x)
.