2011-09-16 10 views
59

Acabo de escribir un pequeño método para contar el número de páginas de SMS del teléfono celular. No tuve la opción de redondear usando Math.ceil, y honestamente parece ser muy feo.¿Cómo redondear la división de enteros y tener el resultado int en Java?

Aquí está mi código:

public class Main { 

/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) { 
    String message = "today we stumbled upon a huge performance leak while optimizing a raycasting algorithm. Much to our surprise, the Math.floor() method took almost half of the calculation time: 3 floor operations took the same amount of time as one trilinear interpolation. Since we could not belive that the floor-method could produce such a enourmous overhead, we wrote a small test program that reproduce"; 

    System.out.printf("COunt is %d ",(int)messagePageCount(message)); 



} 

public static double messagePageCount(String message){ 
    if(message.trim().isEmpty() || message.trim().length() == 0){ 
     return 0; 
    } else{ 
     if(message.length() <= 160){ 
      return 1; 
     } else { 
      return Math.ceil((double)message.length()/153); 
     } 
    } 
} 

realmente no me gusta este trozo de código y estoy buscando una forma más elegante de hacer esto. Con esto, estoy esperando 3 y no 3.0000000. ¿Algunas ideas?

+1

posible duplicado de [Cómo redondear el resultado de la división de enteros] (http: // stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division) – Raedwald

Respuesta

79

para reunir a una división entera puede utilizar

import static java.lang.Math.abs; 

public static long roundUp(long num, long divisor) { 
    int sign = (num > 0 ? 1 : -1) * (divisor > 0 ? 1 : -1); 
    return sign * (abs(num) + abs(divisor) - 1)/abs(divisor); 
} 

o si ambos números son positivos

public static long roundUp(long num, long divisor) { 
    return (num + divisor - 1)/divisor; 
} 
+0

Tenga en cuenta que esto solo funciona para 'num> = 0'. – user905686

+0

Redondea al infinito positivo. No redondea desde cero, que es otra opción. –

+2

Quiero decir, intente 'num = -2' y' div = -3'. Esto termina en '-6/-3 = 2' pero' 0,666..' debe redondearse a '1'. De hecho, no funciona para 'num <= 0 && div <= 0'. – user905686

10
(message.length() + 152)/153 

Esto dará un entero "redondeado".

0

esto podría ser atento ,, reste el resto al legnth y que sea una número divisible y luego divídalo con 153

int r=message.length()%153;  //Calculate the remainder by %153 
return (message.length()-r)/153; // find the pages by adding the remainder and 
            //then divide by 153 
1

Ex panding en la solución de Peter, esto es lo que he encontrado que funciona para mí que siempre ronda 'hacia el infinito positivo':

public static long divideAndRoundUp(long num, long divisor) { 
    if (num == 0 || divisor == 0) { return 0; } 

    int sign = (num > 0 ? 1 : -1) * (divisor > 0 ? 1 : -1); 

    if (sign > 0) { 
     return (num + divisor - 1)/divisor; 
    } 
    else { 
     return (num/divisor); 
    } 
} 
+0

La división por cero no es cero, pero debería ser un error. –

95

Uso Math.ceil() y arrojo el resultado a int:

  • Esto es aún más rápido que evitar dobles usando abs().
  • El resultado es correcto cuando se trabaja con negativos, porque -0,999 se redondeará a 0

Ejemplo:

(int) Math.ceil((double)divident/divisor); 
+3

Esta debería ser la respuesta correcta – Duane

+1

@Duane El OP dice "No tuve la opción de redondear usando Math.ceil" – Hemmels

+0

Punto justo, aunque creo que este es el mejor "redondeo matemático" en google ahora :) . Es una pena que tenga esa condición. – Duane

6
long numberOfPages = new BigDecimal(resultsSize).divide(new BigDecimal(pageSize), RoundingMode.UP).longValue(); 
+0

+1 para usar funciones incorporadas –

21

Otro de una sola línea que no es demasiado complicado:

private int countNumberOfPages(int numberOfObjects, int pageSize) { 
    return numberOfObjects/pageSize + (numberOfObjects % pageSize == 0 ? 0 : 1); 
} 

Podría usar long en lugar de int; simplemente cambie los tipos de parámetros y el tipo de retorno.

+2

Esta debería ser la respuesta. Probablemente sea el método más fácil de implementar y que evite no realizar ningún paso adicional innecesario. También evita problemas menores de adición cuando se convierte a diferentes tipos numéricos. –

+0

Buena solución. Gracias – ghui

1

Si desea calcular a dividido por b redondea puede utilizar (a + (- a% b))/b

0

si desea importar nada, sugiero esto:

int var = message.length()/153; //you can put any integer instead of 153 depend on your case 
if(message.length() % 153 != 0) 
    var = var + 1; 
8

biblioteca de guayaba de Google handles this in the IntMath class:

IntMath.divide(numerator, divisor, RoundingMode.CEILING); 

A diferencia de muchas respuestas aquí, que maneja los números negativos. También arroja una excepción apropiada al intentar dividir por cero.

Cuestiones relacionadas