Respostas:
Você está fazendo o 157/32que é dividir dois inteiros entre si, o que sempre resulta em um inteiro arredondado para baixo. Portanto, o (int) Math.ceil(...)não está fazendo nada. Existem três soluções possíveis para alcançar o que deseja. Eu recomendo usar a opção 1 ou a opção 2 . Por favor, não use a opção 0 .
## Opção 0
Converta ae bpara um duplo, e você pode usar a divisão e Math.ceilcomo você queria que funcionasse. No entanto, eu desencorajo fortemente o uso dessa abordagem, porque a divisão dupla pode ser imprecisa. Para ler mais sobre a imprecisão das duplas, consulte esta questão .
int n = (int) Math.ceil((double) a / b));
##Opção 1
int n = a / b + ((a % b == 0) ? 0 : 1);
Você faz a / bcom always floor se ae bforem ambos inteiros. Então você tem uma instrução if inline que verifica se você deve ou não teto em vez de chão. Portanto, +1 ou +0, se houver um resto com a divisão, você precisará de +1. a % b == 0verifica o restante.
##Opção 2
Esta opção é muito curta, mas talvez para alguns menos intuitiva. Acho que essa abordagem menos intuitiva seria mais rápida do que a abordagem de divisão dupla e comparação:
Observe que isso não funciona para b < 0.
int n = (a + b - 1) / b;
Para reduzir a chance de estouro, você pode usar o seguinte. No entanto, observe que não funciona para a = 0e b < 1.
int n = (a - 1) / b + 1;
## Explicação por trás da "abordagem menos intuitiva"
Uma vez que dividir dois inteiros em Java (e na maioria das outras linguagens de programação) sempre irá limitar o resultado. Assim:
int a, b;
int result = a/b (is the same as floor(a/b) )
Mas não queremos floor(a/b), mas ceil(a/b)e usando as definições e gráficos da Wikipedia :
Com estes lotes da função chão e tecto é possível ver a relação.

Você pode ver isso floor(x) <= ceil(x). Nós precisamos floor(x + s) = ceil(x). Portanto, precisamos encontrar s. Se pegarmos 1/2 <= s < 1, vai dar certo (experimente alguns números e você verá que sim, eu mesmo acho difícil provar isso). E 1/2 <= (b-1) / b < 1então
ceil(a/b) = floor(a/b + s)
= floor(a/b + (b-1)/b)
= floor( (a+b-1)/b) )
Esta não é uma prova real, mas espero que você esteja satisfeito com ela. Se alguém puder explicar melhor eu também agradeceria. Talvez pergunte no MathOverflow .
157/32 é int/int, o que resulta em um int.
Tente usar o literal dupla - 157/32d, o que é int/double, o que resulta em um double.
157/32é uma divisão inteira porque todos os literais numéricos são inteiros, a menos que seja especificado de outra forma com um sufixo ( dpara double lfor long)
a divisão é arredondada para baixo (para 4) antes de ser convertida para um duplo (4,0), que é então arredondado para cima (para 4,0)
se você usar variáveis, pode evitar que
double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
Ninguém mencionou o mais intuitivo:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
Esta solução corrige a imprecisão da divisão dupla .
Em Java, adicionar um .0 tornará um duplo ...
int total = (int) Math.ceil(157.0 / 32.0);
Ao dividir dois inteiros, por exemplo,
int c = (int) a / (int) b;
o resultado é um int, o valor do qual é adividido por b, arredondado para zero. Porque o resultado já está arredondado, ceil()não faz nada. Observe que esse arredondamento não é o mesmo que floor(), que arredonda para o infinito negativo. Então, 3/2igual 1(e floor(1.5)igual 1.0, mas (-3)/2igual -1(mas floor(-1.5)igual -2.0).
Isso é significativo porque se a/bfosse sempre o mesmo que floor(a / (double) b), você poderia apenas implementar ceil()de a/bcomo -( (-a) / b).
A sugestão de obter ceil(a/b)de
int n = (a + b - 1) / b;, que é equivalente a a / b + (b - 1) / b, ou(a - 1) / b + 1
funciona porque ceil(a/b)é sempre um maior que floor(a/b), exceto quando a/bé um número inteiro. Portanto, você deseja aumentar (ou ultrapassar) o próximo número inteiro, a menos que a/bseja um número inteiro. Adicionar 1 - 1 / bfará isso. Para números inteiros, não vai empurrá-los para o próximo número inteiro. Para todo o resto, sim.
Caramba. Esperançosamente, isso faz sentido. Tenho certeza de que há uma maneira matematicamente mais elegante de explicar isso.
Além disso, para converter um número inteiro em real, você pode adicionar um ponto:
int total = (int) Math.ceil(157/32.);
E o resultado de (157/32.) Também será real. ;)
Verifique a solução abaixo para sua dúvida:
int total = (int) Math.ceil(157/32);
Aqui você deve multiplicar Numerator por 1.0, então ele dará sua resposta.
int total = (int) Math.ceil(157*1.0/32);
Java fornece apenas divisão de piso /por padrão. Mas podemos escrever teto em termos de piso . Vamos ver:
Qualquer número inteiro ypode ser escrito com o formulário y == q*k+r. De acordo com a definição de divisão do piso (aqui floor) que completa r,
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
e da divisão do teto (aqui ceil) que arredonda para cima r₁,
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
onde podemos substituir r+1por r₁:
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
Em seguida, substituímos a primeira equação na terceira para qobter
ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1
Finalmente, dado qualquer inteiro yonde y = q*k+r+1há algum q, k, r, temos
ceil(y, k) == floor(y-1, k) + 1
E nós terminamos. Espero que isto ajude.
ceilé definido como tal na definição intuitiva, em particular quando estamos tomando o teto de um número inteiro, ou seja, r1 = k. Já que os casos extremos são o que há de complicado nisso, acho que precisa ser explicado um pouco mais.
Existem dois métodos pelos quais você pode arredondar o seu valor duplo.
Se você quiser sua resposta 4,90625 como 4, você deve usar Math.floor e se você quiser sua resposta 4,90625 como 5, você pode usar Math.ceil
Você pode consultar o código a seguir para isso.
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
ou mais geral
(a-1)/b +1