你正在做157/32
将两个整数相除,结果总是向下舍入的整数。因此(int) Math.ceil(...)
没有做任何事情。有三种可能的解决方案可以实现您想要的目标。我推荐使用任一option 1 or option 2。请这样做NOT use option 0.
Option 0
Convert a
and b
到双精度,您可以使用除法和Math.ceil
正如你所希望的那样。然而,我强烈反对使用这种方法,因为双除法可能不精确。要了解有关双打不精确性的更多信息,请参阅这个问题 https://stackoverflow.com/questions/10444350/c-sharp-loss-of-precision-when-dividing-doubles.
int n = (int) Math.ceil((double) a / b));
Option 1
int n = a / b + ((a % b == 0) ? 0 : 1);
You do a / b
总是地板如果a
and b
都是整数。然后你有一个内联 if 语句,它检查是否应该使用 ceil 而不是 Floor。所以+1或+0,如果除法有余数,则需要+1。a % b == 0
检查剩余部分。
Option 2
这个选项很短,但可能对于一些不太直观的人来说。我认为这种不太直观的方法会比双除法和比较方法更快:
请注意,这不适用于b < 0
.
int n = (a + b - 1) / b;
为了减少溢出的可能性,您可以使用以下内容。但请注意,它不适用于a = 0
and b < 1
.
int n = (a - 1) / b + 1;
“不太直观的方法”背后的解释
因为在 Java(以及大多数其他编程语言)中将两个整数相除总是会将结果取整。所以:
int a, b;
int result = a/b (is the same as floor(a/b) )
But we don't want floor(a/b)
, but ceil(a/b)
, and using the definitions and plots from Wikipedia http://en.wikipedia.org/wiki/Floor_and_ceiling_functions:
通过这些地板和天花板函数的图,您可以看到其中的关系。
你可以看到floor(x) <= ceil(x)
。我们需要floor(x + s) = ceil(x)
。所以我们需要找到s
。如果我们采取1/2 <= s < 1
它会是正确的(尝试一些数字,你会发现确实如此,我发现自己很难证明这一点)。和1/2 <= (b-1) / b < 1
, so
ceil(a/b) = floor(a/b + s)
= floor(a/b + (b-1)/b)
= floor( (a+b-1)/b) )
这不是真正的证据,但我希望你满意。如果有人能更好地解释它,我也会很感激。也许可以问一下数学溢出 https://mathoverflow.net/.