Respuestas:
Lo que está haciendo 157/32
es dividir dos enteros entre sí, lo que siempre resulta en un entero redondeado hacia abajo. Por lo tanto, (int) Math.ceil(...)
no está haciendo nada. Hay tres posibles soluciones para lograr lo que desea. Yo recomiendo usar ya sea la opción 1 o la opción 2 . Por favor, NO utilice la opción 0 .
## Opción 0
Convierta a
y b
en un doble, y puede usar la división y Math.ceil
como desea que funcione. Sin embargo, desaconsejo encarecidamente el uso de este enfoque, porque la doble división puede ser imprecisa. Para leer más sobre la imprecisión de los dobles, consulte esta pregunta .
int n = (int) Math.ceil((double) a / b));
##Opción 1
int n = a / b + ((a % b == 0) ? 0 : 1);
Lo haces a / b
con siempre suelo si a
y b
ambos son enteros. Luego tiene una instrucción if en línea que verifica si debe o no ceil en lugar de floor. Entonces +1 o +0, si hay un resto con la división, necesita +1. a % b == 0
cheques para el resto.
##Opcion 2
Esta opción es muy corta, pero quizás para algunos menos intuitivos. Creo que este enfoque menos intuitivo sería más rápido que el enfoque de doble división y comparación:
tenga en cuenta que esto no funciona b < 0
.
int n = (a + b - 1) / b;
Para reducir la posibilidad de desbordamiento, puede utilizar lo siguiente. Sin embargo, tenga en cuenta que no funciona para a = 0
y b < 1
.
int n = (a - 1) / b + 1;
## Explicación detrás del "enfoque menos intuitivo"
Dado que dividir dos enteros en Java (y la mayoría de los otros lenguajes de programación) siempre basará el resultado. Entonces:
int a, b;
int result = a/b (is the same as floor(a/b) )
Pero no queremos floor(a/b)
, pero ceil(a/b)
, y usando las definiciones y gráficos de Wikipedia :
Con estas gráficas de la función suelo y techo se puede ver la relación.
Puedes ver eso floor(x) <= ceil(x)
. Necesitamos floor(x + s) = ceil(x)
. Entonces tenemos que encontrar s
. Si lo tomamos 1/2 <= s < 1
, será correcto (pruebe algunos números y verá que sí, me resulta difícil probarlo). Y 1/2 <= (b-1) / b < 1
asi
ceil(a/b) = floor(a/b + s)
= floor(a/b + (b-1)/b)
= floor( (a+b-1)/b) )
Esta no es una prueba real, pero espero que esté satisfecho con ella. Si alguien puede explicarlo mejor, también lo agradecería. Quizás preguntarlo en MathOverflow .
157/32 es int/int
, lo que da como resultado un int
.
Intente usar el doble literal - 157/32d
, que es int/double
, que da como resultado un double
.
157/32
es una división de enteros porque todos los literales numéricos son enteros a menos que se especifique lo contrario con un sufijo ( d
para doble l
para largo)
la división se redondea hacia abajo (a 4) antes de convertirse en un doble (4.0) que luego se redondea hacia arriba (a 4.0)
si usa variables, puede evitarlo
double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
Nadie ha mencionado lo más intuitivo:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
Esta solución corrige la imprecisión de la doble división.
En Java, agregar un .0 lo convertirá en un doble ...
int total = (int) Math.ceil(157.0 / 32.0);
Al dividir dos enteros, por ejemplo,
int c = (int) a / (int) b;
el resultado es un int
, cuyo valor se a
divide entre b
, redondeado hacia cero. Como el resultado ya está redondeado, ceil()
no hace nada. Tenga en cuenta que este redondeo no es el mismo que floor()
, que redondea hacia el infinito negativo. Entonces, 3/2
es igual 1
(y floor(1.5)
es igual 1.0
, pero (-3)/2
es igual -1
(pero floor(-1.5)
es igual -2.0
)).
Esto es importante porque si a/b
siempre fueron los mismos que floor(a / (double) b)
, a continuación, usted podría aplicar ceil()
de a/b
tan -( (-a) / b)
.
La sugerencia de obtener ceil(a/b)
de
int n = (a + b - 1) / b;
, que es equivalente a a / b + (b - 1) / b
, o(a - 1) / b + 1
funciona porque ceil(a/b)
siempre es uno mayor que floor(a/b)
, excepto cuando a/b
es un número entero. Por lo tanto, desea subirlo (o pasar) al siguiente número entero, a menos que a/b
sea un número entero. Agregar 1 - 1 / b
hará esto. Para números enteros, no los empujará al siguiente número entero. Para todo lo demás, lo hará.
¡Ay! Ojalá tenga sentido. Estoy seguro de que hay una forma matemáticamente más elegante de explicarlo.
Además, para convertir un número de entero a número real, puede agregar un punto:
int total = (int) Math.ceil(157/32.);
Y el resultado de (157/32.) También será real. ;)
int total = (int) Math.ceil( (double)157/ (double) 32);
Compruebe la solución a continuación para su pregunta:
int total = (int) Math.ceil(157/32);
Aquí debe multiplicar Numerador por 1.0, luego dará su respuesta.
int total = (int) Math.ceil(157*1.0/32);
Java proporciona solo división de piso /
de forma predeterminada. Pero podemos escribir techo en términos de piso . Veamos:
Cualquier número entero y
se puede escribir con el formulario y == q*k+r
. De acuerdo con la definición de división de piso (aquí floor
) que completa r
,
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
y de la división del techo (aquí ceil
) que se redondea r₁
,
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
donde podemos sustituir r+1
por r₁
:
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
Luego sustituimos la primera ecuación en la tercera para q
obtener
ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1
Por último, dado cualquier número entero y
, donde y = q*k+r+1
para algunos q
, k
, r
, tenemos
ceil(y, k) == floor(y-1, k) + 1
Y hemos terminado. Espero que esto ayude.
ceil
queda claro por qué se define como tal a partir de la definición intuitiva, en particular cuando estamos tomando el techo de un número entero, es decir, r1 = k. Dado que los casos extremos son lo complicado de esto, creo que debe explicarse un poco más.
Hay dos métodos mediante los cuales puede redondear su valor doble.
Si desea que su respuesta 4.90625 sea 4, entonces debe usar Math.floor y si desea que su respuesta 4.90625 sea 5, entonces puede usar Math.ceil
Puede consultar el siguiente código para eso.
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
o más general
(a-1)/b +1