Java 使用 Math.ceil 舍入为 int

新手上路,请多包涵
int total = (int) Math.ceil(157/32);

为什么它仍然返回 4? 157/32 = 4.90625 ,我需要四舍五入,我环顾四周,这似乎是正确的方法。

我试过 total 作为 double 类型,但得到 4.0。

我究竟做错了什么?

原文由 tom 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 605
1 个回答

你正在做 157/32 将两个整数彼此相除,结果总是向下舍入的整数。因此 (int) Math.ceil(...) 没有做任何事情。可以通过三种可能的解决方案来实现您想要的。我 建议 使用 选项 1选项 2 。请 不要 使用 选项 0

选项 0

ab 转换为双精度数,您可以使用除法和 Math.ceil ,因为您希望它工作。但是我强烈反对使用这种方法,因为双重除法可能不精确。要了解有关双打不精确的更多信息,请参阅 此问题

 int n = (int) Math.ceil((double) a / b));

选项1

 int n = a / b + ((a % b == 0) ? 0 : 1);

如果 ab 都是整数,你做 a / b 总是 floor 。然后你有一个内联 if 语句,它检查你是否应该 ceil 而不是 floor。所以 +1 或 +0,如果除法有余数,则需要 +1。 a % b == 0 检查余数。

选项 2

这个选项很短,但对于一些人来说可能不太直观。我认为这种不太直观的方法会比双重除法和比较方法更快:

请注意,这不适用于 b < 0

 int n = (a + b - 1) / b;

为了减少溢出的可能性,您可以使用以下内容。但是请注意,它不适用于 a = 0b < 1

 int n = (a - 1) / b + 1;

“不太直观的方法”背后的解释

因为在 Java(和大多数其他编程语言)中将两个整数相除总是会降低结果。所以:

 int a, b;
int result = a/b (is the same as floor(a/b) )

但我们不想要 floor(a/b) ,而是 ceil(a/b) ,并使用 维基百科 的定义和图表:在此处输入图像描述

通过这些 floor 和 ceil 函数图,您可以看到这种关系。

楼层功能细胞功能

你可以看到 floor(x) <= ceil(x) 。我们需要 floor(x + s) = ceil(x) 。所以我们需要找到 s 。如果我们取 1/2 <= s < 1 它将是正确的(尝试一些数字,你会看到它是正确的,我发现自己很难证明这一点)。和 1/2 <= (b-1) / b < 1 ,所以

ceil(a/b) = floor(a/b + s)
          = floor(a/b + (b-1)/b)
          = floor( (a+b-1)/b) )

这不是真正的证明,但我希望你对它感到满意。如果有人能更好地解释它,我也会很感激。也许在 MathOverflow 上询问。

原文由 martijnn2008 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题