Java使用Math.ceil四舍五入为int
int total = (int) Math.ceil(157/32);
为什么它仍然返回4? 157/32 = 4.90625
,我需要四舍五入,环顾四周,这似乎是正确的方法。
我total
尝试了double
types,但得到4.0。
我究竟做错了什么?
你正在做157/32
,它将两个整数相互分开,这总是导致一个舍入整数。 因此(int) Math.ceil(...)
没有做任何事情。 有三种可能的解决scheme来实现你想要的。 我build议使用选项1或选项2 。 请不要使用选项0 。
选项0
将a
和b
转换a
double,您可以使用除法和Math.ceil
如您所愿。 不过,我强烈不鼓励使用这种方法,因为双重划分可能是不准确的。
int n = (int) Math.ceil((double) a / b));
选项1
int n = a / b + (a % b == 0) ? 0 : 1;
如果a
和b
都是整数,那么你总是用floor来做a / b
。 然后,你有一个内联if语句的女巫检查你是否应该ceil而不是地板。 所以+1或+0,如果有一个余数与分区,你需要+1。 a % b == 0
检查余数。
选项2
这个选项很短,但也许不那么直观。 我认为这种不太直观的方法比双重划分和比较方法更快:
int n = (a + b - 1) / b;
为了减less溢出的机会,你可以使用下面的内容。 但请注意,它不适用于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中的定义和图表:
有了这些地板和细胞function的情节,你可以看到这种关系。
你可以看到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
等于1
( floor(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
,其中对于某个q
, k
, r
, y = 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