2013-03-26 16 views
5

Per stabilire il contesto, sto parlando solo di aritmetica dei numeri interi, su numeri interi grandi, quindi passare per virgola mobile non è un'opzione e utilizzare numeri negativi, quindi la differenza tra divisione suddivisa in aree e troncata.Divisione troncata rispetto a pavimento in Python

Quando si esegue la divisione su numeri interi negativi, i tipici linguaggi di programmazione della famiglia C e hardware forniscono il risultato troncato, ad es. 1/-2 = 0. Python 2 dà il risultato sul pavimento per es. 1/-2 = -1.

Nonostante gli argomenti su cui è intrinsecamente migliore, c'è un modo per ottenere Python per fornire il risultato troncato? Fa alcuna differenza se usi Python 3 invece di 2?

risposta

7

Ok, se si desidera solo una soluzione, ricordate int tronca il numero, quindi invece di fare interi Divison, troncare una galleggiante con int

int(1./-2) 

Se si sta utilizzando Python 3.x, si può semplicemente fare

int(1/2) 

Se si desidera che lo stesso comportamento in Py divisione 2.X importazione dal futuro

from __future__ import division 
int(1/2) 

Se volete sapere il motivo esatto per questo comportamento, leggere questo bellissimo articolo Why Python's Integer Division Floors


Guardando la vostra situazione nel usando float per la divisione, qui è un approccio alternativo che sembra funzionare per quanto Ho provato Sentitevi liberi di farmi sapere di eventuali problemi che si trovano ad affrontare

>>> def trunc_div(a,b): 
    q, r = divmod(a,b) 
    if q < 0 and r: 
     q += 1 
    return q 

>>> trunc_div(1,-2) 
0 
>>> trunc_div(999999999999999999999999999999999999999999, -2) 
-499999999999999999999999999999999999999999L 
>>> trunc_div(999999999999999999999999999999999999999999, 2) 
499999999999999999999999999999999999999999L 
>>> trunc_div(1,2) 
0 
>>> 
+0

Prova 'int (100000000000000000000000./2)' ... (macchina a 32 bit) –

+0

Ancora una volta, sto parlando solo di aritmetica intera, non di virgola mobile. Capisco le ragioni per cui il pavimento è intrinsecamente migliore, ma come ho detto, questa è una domanda diversa; quello che sto cercando in questo contesto è un modo per emulare il comportamento dell'hardware tipico e dei linguaggi di programmazione. – rwallace

+0

@rwallace: vedere il mio aggiornamento – Abhijit

1

Python 3 ha divisione new-style (che può anche essere attivato in Python 2 con from __future__ import division):

>>> from __future__ import division 
>>> -1/2 
-0.5 
>>> -1 // 2 
-1 

Non credo che si può ottenere la divisione troncata, si sarebbe probabilmente necessario utilizzare la matematica .pavimento().

+0

Questo è pavimentato, non troncato. Di nuovo, sto parlando solo di aritmetica intera, il punto in virgola mobile non è affatto coinvolto. – rwallace

+0

Ah sì, mi dispiace, li ho confusi. – djc

1

Credo che questo risolve il problema, ma è una chiamata di funzione, non è una semplice operazione:

def truncdiv(a, b): 
    if a < 0: 
     a = -a 
     b = -b 
    if b < 0: 
     return (a + b + 1)/b 
    return a/b 
0

I gmpy2 supporti biblioteca divisione troncata:

>>> import gmpy2 
>>> gmpy2.mpz(-100)//7 
mpz(-15) 
>>> gmpy2.t_div(gmpy2.mpz(-100),7) 
mpz(-14) 
>>> 

Disclaimer: Gestisco gmpy2.