Domanda

Per favore, puoi dirmi quanto costa? (-2) % 5?Secondo il mio interprete Python è 3, ma hai una saggia spiegazione per questo?

Ho letto che in alcune lingue il risultato può dipendere dalla macchina, ma non ne sono sicuro.

È stato utile?

Soluzione

A proposito:la maggior parte dei linguaggi di programmazione non sarebbe d'accordo con Python e fornirebbe il risultato -2.A seconda dell'interpretazione del modulo questo è corretto.Tuttavia, la definizione matematica più condivisa afferma che il modulo di UN E B è il resto (strettamente positivo). R della divisione di UN / B.Più precisamente, 0 <= R < B per definizione.

Altri suggerimenti

Il risultato dell'operazione del modulo sui negativi sembra dipendere dal linguaggio di programmazione ed ecco un elenco http://en.wikipedia.org/wiki/Modulo_operazione

Il tuo interprete Python ha ragione.Un modo (stupido) per calcolare un modulo è sottrarre o aggiungere il modulo fino a quando il valore risultante è compreso tra 0 e (modulo − 1).

per esempio.:13 mod 5 = (13 − 5) mod 5 = (13 − 10) mod 5 = 3

o nel tuo caso:−2 mod 5 = (−2 + 5) mod 5 = 3

Come dice la documentazione in Operazioni aritmetiche binarie, Python assicura che:

La divisione intera e gli operatori modulo sono collegati dalla seguente identità: x == (x/y)*y + (x%y).La divisione intera e il modulo sono collegati anche alla funzione integrata divmod(): divmod(x, y) == (x/y, x%y).

E veramente,

>>> divmod(-2, 5)
(-1, 3).

Un altro modo per visualizzare l'uniformità di questo metodo è calcolare divmod per una piccola sequenza di numeri:

>>> for number in xrange(-10, 10):
...     print divmod(number, 5)
...
(-2, 0)
(-2, 1)
(-2, 2)
(-2, 3)
(-2, 4)
(-1, 0)
(-1, 1)
(-1, 2)
(-1, 3)
(-1, 4)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)

Bene, 0% 5 dovrebbe essere 0, giusto?

-1 % 5 dovrebbe essere 4 perché è la successiva cifra consentita che va nella direzione opposta (vale a dire, non può essere 5, poiché è fuori intervallo).

E seguendo questa logica, -2 deve essere 3.

Il modo più semplice per pensare a come funzionerà è continuare ad aggiungere o sottrarre 5 finché il numero non rientra tra 0 (incluso) e 5 (escluso).

Non sono sicuro della dipendenza dalla macchina: non ho mai visto un'implementazione che lo fosse, ma non posso dire che non sia mai stata eseguita.

Come spiegato in altre risposte, ci sono molte scelte per un'operazione modulo con valori negativi.In generale linguaggi diversi (e architetture di macchine diverse) daranno risultati diversi.

Secondo il Manuale di riferimento di Python,

L'operatore modulo produce sempre un risultato con lo stesso segno del suo secondo operando (o zero);il valore assoluto del risultato è strettamente inferiore al valore assoluto del secondo operando.

è la scelta presa da Python.Fondamentalmente il modulo è definito in modo che valga sempre:

x == (x/y)*y + (x%y)

quindi ha senso che (-2)%5 = -2 - (-2/5)*5 = 3

Bene, -2 diviso 5 sarebbe 0 con resto 3.Non credo che dovrebbe dipendere molto dalla piattaforma, ma ho visto cose più strane.

Infatti sono 3.In aritmetica modulare, un modulo è semplicemente il resto di una divisione e il resto di -2 diviso per 5 è 3.

Il risultato dipende dalla lingua.Python restituisce il segno del divisore, dove ad esempio c# restituisce il segno del dividendo (es.-2 % 5 restituisce -2 in c#).

Una spiegazione potrebbe essere che i numeri negativi vengono memorizzati utilizzando complemento a 2.Quando l'interprete Python tenta di eseguire l'operazione modulo, la converte in un valore senza segno.Pertanto, invece di fare (-2) % 5, in realtà calcola 0xFFFF_FFFF_FFFF_FFFD % 5 che è 3.

Fare attenzione a non fare affidamento su questo comportamento mod in C/C++ su tutti i sistemi operativi e le architetture.Se ricordo bene, ho provato a fare affidamento su codice C/C++ come

float x2 = x % n;

per mantenere x2 nell'intervallo da 0 a n-1 ma i numeri negativi si insinuavano quando compilavo su un sistema operativo, ma le cose funzionavano bene su un altro sistema operativo.Ciò ha reso il debugging diabolico poiché è successo solo la metà delle volte!

Sembra esserci una comune confusione tra i termini "modulo" e "resto".

In matematica, dovrebbe esserci un resto Sempre essere definito coerente con il quoziente, per cui se a / b == c rem d Poi (c * b) + d == a.A seconda di come arrotondi il quoziente, ottieni resti diversi.

Tuttavia, il modulo dovrebbe sempre dare un risultato 0 <= r < divisor, che è coerente con la divisione da arrotondamento a meno infinito solo se si consentono numeri interi negativi.Se la divisione arrotonda verso lo zero (cosa comune), modulo e resto sono equivalenti solo per valori non negativi.

Alcuni linguaggi (in particolare C e C++) non definiscono i comportamenti di arrotondamento/resto richiesti e % è ambiguo.Molti definiscono l'arrotondamento come verso lo zero, ma usano il termine modulo dove resto sarebbe più corretto.Python è relativamente insolito in quanto arrotonda all'infinito negativo, quindi modulo e resto sono equivalenti.

Ada arrotonda verso lo zero IIRC, ma ha entrambi mod E rem operatori.

La politica C ha lo scopo di consentire ai compilatori di scegliere l'implementazione più efficiente per la macchina, ma l'IMO è una falsa ottimizzazione, almeno al giorno d'oggi.Un buon compilatore sarà probabilmente in grado di utilizzare l'equivalenza per l'ottimizzazione ovunque non possa verificarsi un numero negativo (e quasi certamente se si utilizzano tipi senza segno).D'altra parte, dove possono verificarsi numeri negativi, quasi certamente ti preoccupi dei dettagli: per motivi di portabilità devi utilizzare algoritmi e/o controlli sovracomplessi progettati con molta attenzione per assicurarti di ottenere i risultati desiderati indipendentemente dall'arrotondamento e dal resto comportamento.

In altre parole, il guadagno derivante da questa "ottimizzazione" è per lo più (se non sempre) un'illusione, mentre in alcuni casi ci sono costi molto reali - quindi è una falsa ottimizzazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top