Answers:
您正在执行的操作157/32
是彼此除以两个整数,这总是导致四舍五入的整数。因此,(int) Math.ceil(...)
什么也没做。有三种可能的解决方案来实现您想要的。我建议使用选项1或选项2。请不要使用选项0。
##选项0
将a
和转换b
为双精度,然后可以使用除法并按Math.ceil
需要工作。但是,我强烈不鼓励使用这种方法,因为双重除法可能不精确。要了解更多关于不精确的双打看到这个问题。
int n = (int) Math.ceil((double) a / b));
##选项1
int n = a / b + ((a % b == 0) ? 0 : 1);
你a / b
有永远地板如果a
和b
都是整数。然后,您有一个内联的if语句女巫检查您是否应该天花板而不是地板。因此+1或+0,如果除法除法运算中还有余数,则需要+1。a % b == 0
检查其余部分。
##选项2
此选项很短,但可能不太直观。我认为这种不太直观的方法会比双重除法和比较方法要快:
请注意,这不适用于b < 0
。
int n = (a + b - 1) / b;
为了减少溢出的机会,您可以使用以下方法。但是请注意,它不适用于a = 0
和b < 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)
使用Wikipedia的定义和情节:
使用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上询问。
157/32为int/int
,则结果为int
。
尝试使用双字面量- 157/32d
,即会int/double
导致double
。
没有人提到最直观的:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
该解决方案解决了双分割不精确问题。
当除以两个整数时,例如,
int c = (int) a / (int) b;
结果是an int
,其值a
除以b
,并四舍五入为零。由于结果已经四舍五入,因此ceil()
不会执行任何操作。请注意,此舍入与的舍入不同floor()
,后者朝负无穷大舍入。因此,3/2
等于1
(和floor(1.5)
等于1.0
,但(-3)/2
等于-1
(但floor(-1.5)
等于-2.0
)。
因为如果这是显著a/b
总是一样的floor(a / (double) b)
,那么你可以只实施ceil()
的a/b
作为-( (-a) / b)
。
ceil(a/b)
来自的建议
int n = (a + b - 1) / b;
,等效于a / b + (b - 1) / b
或(a - 1) / b + 1
之所以起作用,ceil(a/b)
是因为总是大于floor(a/b)
,除非a/b
是整数。因此,除非a/b
是整数,否则您想将其撞到(或超过)下一个整数。添加1 - 1 / b
将执行此操作。对于整数,它不会完全推升到下一个整数。对于其他一切,它都会。
kes 希望这是有道理的。我敢肯定,有一种数学上更优雅的方式来解释它。
同样,要将数字从整数转换为实数,您可以添加一个点:
int total = (int) Math.ceil(157/32.);
并且(157/32。)的结果也将是真实的。;)
Java /
默认仅提供地板分割。但是我们可以用地板来写天花板。让我们来看看:
任何整数y
都可以用形式书写y == q*k+r
。根据floor
四舍五入的楼层划分(在此)的定义r
,
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
和ceil
四舍五入的天花板分区(在此)r₁
,
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
在这里我们可以替换r+1
为r₁
:
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
然后我们替换第一方程式为第三为q
获得
ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1
最后,给定任意整数y
,其中y = q*k+r+1
一些q
,k
,r
,我们有
ceil(y, k) == floor(y-1, k) + 1
我们完成了。希望这可以帮助。
ceil
从直观定义中就这样定义,特别是在我们采用整数ceil的情况下,即r1 = k。由于边缘情况是棘手的问题,因此我认为还需要进一步说明。
您可以通过两种方法舍入双精度值。
如果您希望答案4.90625为4,则应使用Math.floor;如果您希望答案4.90625为5,则可以使用Math.ceil
您可以参考以下代码。
public class TestClass {
public static void main(String[] args) {
int floorValue = (int) Math.floor((double)157 / 32);
int ceilValue = (int) Math.ceil((double)157 / 32);
System.out.println("Floor: "+floorValue);
System.out.println("Ceil: "+ceilValue);
}
}
int total = (157-1)/32 + 1
或更一般
(a-1)/b +1