2013-10-22 14 views
18

Cosa deve restituire la divisione intero -1/5? Sono totalmente confuso da questo comportamento. Penso che matematicamente dovrebbe essere 0, ma python e ruby ​​stanno ritornando -1.Divisione intera per numero negativo

Perché le lingue diverse si comportano in modo diverso qui? Per favore qualcuno lo spieghi. Grazie.

| Language | Code   | Result | 
|-----------+----------------+--------| 
| ruby  | -1/5   |  -1 | 
| python | -1/5   |  -1 | 
| c   | -1/5   |  0 | 
| clojure | (int (/ -1 5)) |  0 | 
| emacslisp | (/ -1 5)  |  0 | 
| bash  | expr -1/5 |  0 | 
+0

qual è la domanda? Non lo sai? se vuoi saperlo per una qualsiasi delle lingue, provalo? – usethedeathstar

+0

Scusa, intendevo -1 non 1. Non conosco la risposta e mi sento totalmente confuso. – ivs

+9

Non c'è risposta. La "divisione intera" non è un concetto ben definito e le specifiche di ogni lingua possono scegliere la pavimentazione o il troncamento verso 0 come risultato definito per l'operazione. – geoffspear

risposta

31

Risposta breve: i progettisti lingua arrivare a scegliere se il loro linguaggio arrotonderà a zero, infinito negativo, o infinito positivo quando si fa divisione intera. Lingue diverse hanno fatto scelte diverse.

Risposta lunga: Gli autori del linguaggio di Python e Ruby hanno entrambi deciso che l'arrotondamento verso l'infinito negativo ha più senso dell'arrotondamento verso lo zero (come fa C). Il creatore di Python ha scritto un post sul suo ragionamento here. Ne ho estratto molto di seguito.

mi è stato chiesto (di nuovo) oggi per spiegare il motivo per cui divisione intera in Python restituisce il piano del risultato, invece di troncare verso lo zero come C.

Per i numeri positivi, non c'è nessuna sorpresa:

>>> 5//2 
2 

Ma se uno degli operandi è negativo, il risultato è pavimentata, cioè, arrotondato per eccesso (verso l'infinito negativo):

>>> -5//2 
-3 
>>> 5//-2 
-3 

Questo disturba alcune persone, ma c'è una buona ragione matematica. La divisione tra interi (//) e la sua sorella, l'un'operazione di modulo (%), andare insieme e soddisfare una bella matematico rapporto (tutte le variabili sono numeri interi):

a/b = q with remainder r 

tale che

b*q + r = a and 0 <= r < b 
(assuming a and b are >= 0). 

Se si desidera che il rapporto da estendere per negativo un (mantenendo b positiva), sono disponibili due opzioni: se si troncano q verso lo zero, r diventerà negativo, in modo che le modifiche invarianti a 0 < = abs (r) < altrimenti, è possibile floor q verso infinito negativo e l'invariante rimane 0 < = r < b. [aggiornamento: risolto questo paragrafo]

Nella teoria dei numeri matematici, i matematici preferiscono sempre la seconda opzione (vedere ad esempio Wikipedia). Per Python, ho fatto la stessa scelta perché ci sono alcune interessanti applicazioni dell'operazione modulo in cui il segno di a non è interessante. Prendi in considerazione di prendere un timestamp POSIX (secondi dall'inizio del 1970) e trasformarlo in l'ora del giorno. Poiché ci sono 24 * 3600 = 86400 secondi in un giorno, questo calcolo è semplicemente t% 86400. Ma se dovessimo esprimere i tempi prima del 1970 usando numeri negativi, la regola "truncate verso zero" darebbe un risultato senza senso! Usando la regola del piano tutto funziona bene .

+0

Grazie per la risposta! – ivs

4

La divisione intera è specifica dell'implementazione. Da Modulo operation di Wikipedia:

Molte implementazioni utilizzare troncato divisione dove il quoziente è definito da truncation q = trunc ( un/ n), in altre parole è il primo intero nella direzione di 0 dal quoziente razionale esatto e il resto da r = a - n q. A livello informatico, il quoziente è "arrotondato a zero" e il resto ha quindi lo stesso segno del dividendo.

Knuth descritto divisione dove il quoziente è definito dal floor function q = floor ( un/ n) e il resto pavimentata r è

r = a - nq = a - n \left\lfloor {a \over n} \right\rfloor.

Qui il quoziente è sempre arrotondato verso il basso (anche se è già negativo) e il resto ha lo stesso segno del divisore.

Problemi correlati