0

今天早些时候我在问关于半数的问题,并从@alk 那里得到了很大的帮助。在那篇文章中,我的想法是将 4.5 舍入到 5,但将 4.4 舍入到 4。@alk 给出的解决方案是:

int round_number(float x)
{
 return x + 0.5;
}

它工作得非常优雅!

在这篇文章中,我想讨论如何ceil()在 C 中实现该函数。与@alk 给出的最后一个解决方案相同,我想出了以下内容:

int round_up(float y)
{
   return y + 0.99999999;
}

这适用于所有情况,除非浮点数 y 具有 0.00000001。我想知道是否有更好的方法来做与ceil()C相同的事情。

4

3 回答 3

2

除非您可靠地知道 float 的 epsilon(我不确定标准 C 是否提供),否则我认为您会被卡住return (y < 0 || y == (int)y) ? y : y + 1;

于 2014-03-02T04:42:52.223 回答
1

这对负数失败。

int round_up(float y) {
 return y + 0.99999999;
}

但是,让我们利用它来发挥我们的优势。 floatto intconversion 是向 0.0 截断。因此,负数正在执行“向上取整”或“上限”功能。当我们有一个肯定的float,转换为int注意这是一个“地板”功能。调整时y不是整数。

(假设yINT_MIN ... INT_MAX.)

int ceil(float y) {
   if (y < 0) {
     return y;  // this does a ceiling function as y < 0.
   }
   int i = y; // this does a floor function as y >= 0.
   if (i != y) i++;
   return i;
 }

void ceil_test(float y) {
   printf("%f %d\n", y, ceil(y));
}
于 2014-03-02T05:13:10.370 回答
0

第一个片段对负数不正确。-3.5 将是 -3,而不是 -4。正确使用舍入值

int round_number(float x)
{
    if (x >= 0)
        return x + 0.5f;
    else
        return x - 0.5f
}

即使这样,对于 2 个值仍然是不正确的。请参阅为什么 Math.round(0.49999999999999994) 返回 1?. 注意需要使用f后缀来获取float字面量,否则运算会以double精度进行,然后向下转换回float

对于天花板,加 1 就足够了

int ceiling(float x)
{
    if (x < 0 || (int)x == x)
        return x;
    else
        return x + 1.0f;
}

当 x 是整数时,例如 x = 3.0(或 -3.0),它返回 3(或 -3)。对于 x = 3.1 它返回 4,对于 x = -3.1 它返回 -3

于 2014-03-02T07:09:24.443 回答