Java使用Math.ceil四舍五入为int

int total = (int) Math.ceil(157/32); 

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

total尝试了doubletypes,但得到4.0。

我究竟做错了什么?

你正在做157/32 ,它将两个整数相互分开,这总是导致一个舍入整数。 因此(int) Math.ceil(...)没有做任何事情。 有三种可能的解决scheme来实现你想要的。 我build议使用选项1选项2 。 请不要使用选项0

选项0

ab转换a double,您可以使用除法和Math.ceil如您所愿。 不过,我强烈不鼓励使用这种方法,因为双重划分可能是不准确的。

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

选项1

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

如果ab都是整数,那么你总是用floor来做a / b 。 然后,你有一个内联if语句的女巫检查你是否应该ceil而不是地板。 所以+1或+0,如果有一个余数与分区,你需要+1。 a % b == 0检查余数。

选项2

这个选项很短,但也许不那么直观。 我认为这种不太直观的方法比双重划分和比较方法更快:

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

为了减less溢出的机会,你可以使用下面的内容。 但请注意,它不适用于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) ,并使用Wikipedia中的定义和图表: 在这里输入图像说明

有了这些地板和细胞function的情节,你可以看到这种关系。

地板功能Ceil功能

你可以看到floor(x) <= ceil(x) 。 我们需要floor(x + s) = ceil(x) 。 所以我们需要finds 。 如果我们采取1/2 <= s < 1 ,那么就是正确的(尝试一些数字,你会看到它,我发现很难certificate这一点)。 并且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

157/32是一个整数除法,因为所有的数字文字都是整数,除非另外指定后缀( d为长整数l

在四分之一(四)之前,它被转换为一个双倍(4.0),然后被四舍五入(4.0)

如果你使用一个variables,你可以避免这一点

 double a1=157; double a2=32; int total = (int) Math.ceil(a1/a2); 
 int total = (int) Math.ceil((double)157/32); 

在Java中添加一个.0将使它成为一个双…

 int total = (int) Math.ceil(157.0 / 32.0); 
 int total = (int) Math.ceil( (double)157/ (double) 32); 

当划分两个整数时,例如,

int c = (int) a / (int) b;

结果是一个int值,它的值除以b ,向零取整。 因为结果已经四舍五入了, ceil()不会做任何事情。 请注意,这个舍入不同于floor() ,它向负无穷的方向舍入。 因此, 3/2等于1floor(1.5)等于1.0 ,但(-3)/2等于-1 (但floor(-1.5)等于-2.0 )。

这很重要,因为如果a/b总是和floor(a / (double) b) ,那么你可以将a/b ceil()作为-( (-a) / b)

从中获得ceil(a/b)的build议

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将做到这一点。 对于整数,它不会把它推到下一个整数。 对于其他一切,它会的。

让人惊讶。 希望这是有道理的。 我相信有一个更好的math方法来解释它。

此外,要将整数转换为实数,您可以添加一个点:

 int total = (int) Math.ceil(157/32.); 

而(157/32)的结果也是真实的。 ;)

检查下面的解决scheme您的问题:

 int total = (int) Math.ceil(157/32); 

在这里你应该将分子乘以1.0,然后它会给你答案。

 int total = (int) Math.ceil(157*1.0/32); 

使用双投来像

Math.ceil((double)value)或类似的

 Math.ceil((double)value1/(double)value2); 

Java仅提供地板划分/默认情况下。 但是,我们可以写出最高限额的地板 。 让我们来看看:

任何整数y都可以写成y == q*k+r 。 根据舍弃r的floor师(这里是floor )的定义,

 floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1 

ceil的上限分割(在这里是ceil

 ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k 

我们可以用r+1代替r+1 r₁

 ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1 

然后我们用第一个方程代入第三个方程得到

 ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1 

最后,给定任意整数y ,其中对于某个qkry = q*k+r+1

 ceil(y, k) == floor(y-1, k) + 1 

我们完成了。 希望这可以帮助。

没有人提到最直观的:

 int x = Math.round(Math.ceil((double) 157 / 32)); 

这个解决scheme修复了双重的不精确性。

 int total = (157-1)/32 + 1 

或更一般的

 (a-1)/b +1