2009-07-02 9 views
16

C'è una funzione Java o util class che non arrotondamento in questo modo: func(3/2) = 2Esiste una funzione Java o una classe util che esegue l'arrotondamento in questo modo: func (3/2) = 2?

Math.ceil() non aiuta, che per nome avrebbe dovuto fare così. Sono a conoscenza di BigDecimal, ma non ne ho bisogno.

+0

Grazie a tutti, –

+3

Stai cercando solo arrotondamento di 0,5 in su? o arrotondamento di 0,3, ecc.? – jvenema

+0

@jvenema: Esattamente - la maggior parte delle soluzioni proposte presuppone che qualsiasi valore superiore a 1.0 dovrebbe arrotondare a 2. Ad esempio, 7/3 è 2.333 ma arrotonderebbe a 3. Tuttavia, dato l'esempio dall'OP, non è chiaro se questo sia desiderato o no. – GalacticCowboy

risposta

50

Math.ceil() sarà sempre arrotondare, ma si sta facendo divisione intera con 3/2. Pertanto, poiché nella divisione intera 3/2 = 1 (non 1.5) il limite di 1 è 1.

cosa si avrebbe bisogno di fare per raggiungere i risultati desiderati è Math.ceil(3/2.0);

Facendo la divisione per una quantità doppia (2.0), si finisce per fare la divisione in virgola mobile al posto di divisione intera. Pertanto, 3/2.0 = 1.5 e ceil() di 1.5 è sempre 2.

4

Non è questo il solito caso di divisione intera? Prova Math.Ceil dopo aver convertito il numero in un tipo a virgola mobile.

+1

3/2 restituisce solo 1 (un int), quindi Math.ceil() non fa nulla.+1 – AlbertoPL

+0

La divisione intero restituisce il numero più grande che divide in modo uniforme. Permettendoti di usare il modulo per ottenere il resto. – Brian

2

Math.ceil aiuto, purché si utilizzino numeri in virgola mobile. Il problema è che 3/2, nella divisione in interi, è 1. Quando il valore raggiunge qualsiasi funzione, sia Math.ceil o qualcos'altro, il valore è semplicemente 1. Ogni porzione decimale finale è scomparsa.

38

Un po 'di magia nera, e si può fare tutto con numeri interi:

// Divide x by n rounding up 
int res = (x+n-1)/n 
+11

Supponendo che x sia positivo! – Niki

+0

Mi piace molto questo metodo in quanto non ho bisogno di importare Math, cast etc etc .. Grazie! – Mat

+2

@Mat D'altra parte chiunque legga il tuo codice troverà più difficile capire cosa stavi facendo e perché. Questo è un argomento molto più forte contro questo rispetto a quelli che hai elencato per questo. Tuttavia è possibile estrarlo in un metodo correttamente denominato e quindi va bene. – biziclop

-2

hai provato Math.floor()?

+2

Questo è il comportamento opposto di ciò che vuole. – Brian

5

In Java, 3/2 = 1 perché utilizza la divisione intera. Non c'è funzione che possa "risolvere" questo in seguito. Quello che devi fare è forzare una divisione flottante e arrotondare il risultato:

int result = (int)Math.ceil(((float)3)/((float)2)); 
3

Molte lingue "pensano" in questo modo. Se dividi un int in un int, allora dovresti ottenere un int (quindi troncano e ottieni 1 come risultato).

Sappiamo tutti che questo non è vero, ma è così che funzionano. Puoi "imbrogliarli" e fare qualcosa come lanciarne uno a doppio, o usare una doppia rappresentazione: Math.ceil (3.0/2) o Math.ceil((double)3/2), come detto.

1
if (a % b == 0) 
{ 
    return (a/b); 
} 
else 
{ 
    return (a/b) + 1; 
} 

Exploits divisione intera per fare quello che vuoi. Non conosco una funzione matematica che faccia questo, ma perché non far girare il tuo?

+0

"perché non arrotolare il tuo"? A causa della leggibilità del codice. – NeplatnyUdaj

9

Per convertire divisione piano di divisione soffitto:

(numerator + denominator-1)/denominator 

Per convertire divisione piano di divisione arrotondamento:

(numerator + (denominator)/2)/denominator 
+0

Primo equivale anche a: 'ceil (n/d) = fl ((n - 1)/d) + 1' –

1

sotto frammento funziona con interi negativi così:

public static int divRoundUp(int x, int n) { 
    if (n<=0) throw new RuntimeException("conceived wt. pos. dividers (was:"+n+")"); 
    int ret = (x+(n-1)*(x>0?1:0))/n; 
    return ret; 
} 
0

Mi piace la risposta di Randy Proctor. Qui in dettaglio:

Se si vuole fare vero e arrotondamento (vale a dire 3/2 -> 2, ma 17/7 -> 2) con gli interi> 0: uso (dividend + (divisor/2))/divisor invece di dividend/divisor.

Se il dividendo può essere un numero intero (vale a dire negativo consentito): (dividend >= 0) ? ((dividend + divisor/2)/divisor) : ((dividend - divisor/2)/divisor).

Se il dividendo è un numero intero e un divisore qualsiasi numero intero ma 0: (dividend >= 0) ? ((dividend + Math.abs(divisor)/2)/divisor) : ((dividend - Math.abs(divisor)/2)/divisor).

(Si noti che l'aggiunta e la sottrazione possono causare un avvolgente che altrimenti non si verificherebbe, rendendo il risultato non corretto.)

0

Qui è un metodo che ho creato per gestire la divisione int senza usare la matematica rotonda e colata a galleggiare . Funziona per numeri positivi e negativi. Funziona con l'aggiunta della metà del denominatore per compensare l'arrotondamento per difetto

public static int div_Int(int num, int den){ 
    if(num > 0 && den > 0 || num < 0 && den < 0){ 
     return ((2*num)+ den)/(2*den); 
    }else{ 
     return ((2*num)- den)/(2*den); 
    } 

} 
0

Se si desidera dividere solo con 2, si può fare:

n - n/2 

E in generale:

(n - 1)/d + 1 == (n + d - 1)/d 

Questo vale per numeri interi non negativi. Come estenderlo a numeri interi negativi dipende da cosa intendi con "arrotondamenti in questo modo". La divisione intera è arrotondata verso lo zero, mentre Math.ceil() si arrotonda e Math.floor() si conclude. Ad esempio n/2 != (int) Math.floor(n/2.0) per n == -5.

Se si desidera sempre arrotondare, è possibile utilizzare Math.ceil() come in this answer.