2011-09-16 22 views
59

Ho appena scritto un piccolo metodo per contare il numero di pagine per gli SMS del cellulare. Non ho avuto la possibilità di arrotondare utilizzando Math.ceil, e onestamente sembra essere molto brutto.Come arrotondare la divisione intera e avere risultato int in Java?

Ecco il mio codice:

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); 
     } 
    } 
} 

non mi piace molto questo pezzo di codice e sto cercando un modo più elegante di fare questo. Con questo, mi aspetto 3 e non 3.0000000. Qualche idea?

+1

possibile duplicato di [Come arrotondare il risultato della divisione intero] (http: // stackoverflow.it/questions/17944/how-to-round-up-the-result-of-integer-division) – Raedwald

risposta

79

per arrotondare una divisione intera è possibile utilizzare

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 se entrambi i numeri sono positivi

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

Si noti che questo funziona solo per 'num> = 0'. – user905686

+0

Arrotonda all'infinito positivo. Non si arrotonda a zero, che è un'altra opzione. –

+2

Voglio dire, prova 'num = -2' e' div = -3'. Questo finisce in '-6/-3 = 2' ma' 0,666..' deve essere arrotondato a '1'. Infatti non funziona per 'num <= 0 && div <= 0'. – user905686

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

Questo darà un numero intero "arrotondato".

0

questo potrebbe essere utile ,, Sottrarre la parte restante alla legnth e ne fanno un numero divisibile e quindi dividerlo 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 sulla soluzione di Peter, questo è quello che ho trovato per me funziona per sempre rotonda 'verso l'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

Divide per zero non è zero, ma dovrebbe essere un errore. –

95

Usa Math.ceil() e gettato il risultato a int:

  • Questo è ancora più veloce che evitare i doppi usando abs().
  • Il risultato è corretto quando si lavora con negativi, perché -0,999 sarà arrotondata a 0

Esempio:

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

Questa dovrebbe essere la risposta corretta – Duane

+1

@Duane L'OP dice "Non ho avuto l'opzione di arrotondare usando Math.ceil" – Hemmels

+0

Punto giusto, anche se penso che questo sia l'apice dell'arrotondamento della matematica su google ora :) . Peccato che abbia questa condizione. – Duane

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

+1 per l'utilizzo di funzioni integrate –

21

Un'altra-liner che non è troppo complicato:

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

È possibile utilizzare long invece di int; basta cambiare i tipi di parametri e restituire il tipo.

+2

Questa dovrebbe essere la risposta. Probabilmente è il metodo più semplice da implementare ed evitare che non compia passi extra inutili. Evita anche piccoli problemi di aggiunta quando si esegue il casting su tipi numerici diversi. –

+0

Buona soluzione. Grazie – ghui

1

Se si desidera calcolare a diviso b arrotondato è possibile utilizzare (a + (-% B))/b

0

se si desidera importare nulla, vi consiglio questo:

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 Guava di Google handles this in the IntMath class:

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

A differenza di molte risposte qui, gestisce i numeri negativi. Inoltre, genera un'eccezione appropriata quando si tenta di dividere per zero.

Problemi correlati