int total = (int) Math.ceil(157/32);
Why does it still return 4? 157/32 = 4.90625, I need to round up, I've looked around and this seems to be the right method.
157/32 = 4.90625
I tried total as double type, but get 4.0.
total
double
What am I doing wrong?
157/32 is int/int, which results in an int.
int/int
int
Try using the double literal - 157/32d, which is int/double, which results in a double.
157/32d
int/double
157/32是一个整数除法,因为所有的数值文字都是整数,除非另外指定了一个后缀(d表示双 l表示长)
157/32
d
l
除法被四舍五入(到4) ,然后它被转换成一个双(4.0) ,然后四舍五入(到4.0)
if you use a variables you can avoid that
double a1=157; double a2=32; int total = (int) Math.ceil(a1/a2);
int total = (int) Math.ceil((double)157/32);
也可以把一个数字从整数转换成实数,你可以加上一个点:
int total = (int) Math.ceil(157/32.);
(157/32.)的结果也是真实的
int total = (int) Math.ceil( (double)157/ (double) 32);
你正在做的是 157/32,它将两个整数相除,总是得到一个四舍五入的整数。因此 (int) Math.ceil(...)没有任何作用。有三种可能的方法可以达到你想要的效果。我使用 选择1或 选择2的 recommend。请使用 选项0。
(int) Math.ceil(...)
将 a和 b转换为双精度,可以按照需要使用除法和 Math.ceil。然而,我强烈反对使用这种方法,因为双除法可能是不精确的。要了解有关双精度不精确的更多信息,请参见 这个问题。
a
b
Math.ceil
int n = (int) Math.ceil((double) a / b));
int n = a / b + ((a % b == 0) ? 0 : 1);
如果 a和 b都是整数,则始终使用地板执行 a / b。然后有一个内联 if 语句,用于检查是否应该使用 ceil 而不是 floor。所以 + 1或者 + 0,如果有一个除法余数,你需要 + 1。a % b == 0检查余数。
a / b
a % b == 0
这个选项非常短,但是对于一些不太直观的人来说可能是这样。我认为这种不那么直观的方法会比双重除法和比较法更快: 请注意,这不适用于 b < 0。
b < 0
int n = (a + b - 1) / b;
为了减少溢出的可能性,您可以使用以下方法。但是请注意,它不工作的 a = 0和 b < 1。
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),并使用 维基百科中的定义和图形:
floor(a/b)
ceil(a/b)
通过这些地板和天花板函数的图,您可以看到它们之间的关系。
你可以看到 floor(x) <= ceil(x)。我们需要 floor(x + s) = ceil(x)。所以我们需要找到 s。如果我们采用 1/2 <= s < 1,它将是正确的(尝试一些数字,你会看到它做,我发现自己很难证明这一点)。还有 1/2 <= (b-1) / b < 1
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) )
这不是一个真正的证据,但我希望你对此感到满意。如果有人能解释得更好,我也会很感激的。也许在 数学溢出上问问。
在 Java 中,添加一个.0将使它成为一个双..。
int total = (int) Math.ceil(157.0 / 32.0);
int total = (157-1)/32 + 1
或者更一般
(a-1)/b +1
使用双重投像
Math.ceil((double)value)之类的
Math.ceil((double)value)
Math.ceil((double)value1/(double)value2);
除两个整数时,
int c = (int) a / (int) b;
结果是 int,其值为 a除以 b,四舍五入为零。因为结果已经是四舍五入的,所以 ceil()不做任何事情。请注意,这个舍入不同于 floor(),后者向负无穷大舍入。因此,3/2等于 1(floor(1.5)等于 1.0,但是 (-3)/2等于 a0(但是 a1等于 a2)。
ceil()
floor()
3/2
1
floor(1.5)
1.0
(-3)/2
这很重要,因为如果 a/b总是与 floor(a / (double) b)相同,那么您可以将 a/b的 ceil()实现为 -( (-a) / b)。
a/b
floor(a / (double) b)
-( (-a) / b)
建议从以下几个方面获取 ceil(a/b)
int n = (a + b - 1) / b;,相当于 a / b + (b - 1) / b或 (a - 1) / b + 1
a / b + (b - 1) / b
(a - 1) / b + 1
因为 ceil(a/b)总是大于 floor(a/b),除非 a/b是一个整数。因此,您希望将它提升到(或超过)下一个整数,除非 a/b是一个整数。添加 1 - 1 / b就可以做到这一点。对于整数,它不会把它们推到下一个整数。至于其他的,会的。
1 - 1 / b
哎呀。希望这是有意义的。我相信有一个更精确的数学方法来解释它。
检查下面的解决方案来回答你的问题:
这里你应该乘以分子与1.0,然后它会给你的答案。
int total = (int) Math.ceil(157*1.0/32);
Java 默认只提供楼层分区 /,但是我们可以提供 以楼面为单位书写天花板。让我们看看:
/
任何整数 y都可以用形式 y == q*k+r来写。根据楼层划分(这里是 floor)的定义,
y
y == q*k+r
floor
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
和天花板分割(这里 ceil)围绕 r₁,
ceil
r₁
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
我们可以用 r+1代替 r₁:
r+1
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
然后将第一个方程代入第三个方程,得到 q
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,我们有
y = q*k+r+1
k
r
ceil(y, k) == floor(y-1, k) + 1
我们完事了,希望这能帮上忙。
没有人提到最直观的:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
解决了 双倍除法不精确的问题。
有两种方法可以四舍五入你的双值。
如果你想你的答案4.90625为4,那么你应该使用 Math.floor,如果你想你的答案4.90625为5,那么你可以使用 Math.ceil
You can refer following code for that.
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); } }
我知道这是一个老问题,但在我看来,我们有一个更好的方法是使用 BigDecimal,以避免精度损失。顺便说一下,使用这个解决方案,我们有可能使用几个舍入和规模策略。
final var dividend = BigDecimal.valueOf(157); final var divisor = BigDecimal.valueOf(32); final var result = dividend.divide(divisor, RoundingMode.CEILING).intValue();