Perché mod (%) è un operatore matematico fondamentale in molti linguaggi di programmazione?


17

C'è una ragione, storica o no, perché l'operatore del modulo fa parte di un piccolo insieme di operatori standard in quelle che sembrano molte lingue? ( +, -, *, /e %, per Java e C, con **in Ruby e Python).

Sembra strano includere la mod come "fondamentale" (non per bussarla, la uso in abbondanza, ma utilizzo anche esponenziazione, valore assoluto, pavimento / soffitto o altri - sembrano altrettanto utili e necessari). È stata una vecchia decisione presa in una specifica che Java, C, Ruby e Python seguono tutti o una lingua da cui tutti discendono? Per quanto ne so, la maggior parte dei dialetti di Lisp include solo +, -, /e *.

All'inizio mi chiedevo se la mod fosse particolarmente facile da implementare a livello binario (ciò farebbe anche la differenza, per quanto riguarda le decisioni su ciò che dovrebbe essere un operatore "fondamentale" e cosa non dovrebbe?) Ma sembra che non lo sia. È solo molto più comunemente usato nella programmazione di quanto penso?

Risposte:


20

Sono sicuro che è comune perché molte architetture di CPU implementano moduluscome un secondo output dell'istruzione di divisione dei numeri interi.

Non ricordo che fosse presente nelle CPU degli anni '70 (6800, 8080, Z80, 1604, ecc.), Ma negli anni '80 ne avevano Intel 8086 e 8088 e Motorola 6809.

L'architettura delle istruzioni PDP-11 specificava la DIVproduzione di un quoziente e un resto dall'inizio (1970), sebbene le istruzioni MUL e DIV non fossero presenti nei primi progetti, ma potessero essere emulate in modo trasparente da una "trap non implementata da istruzioni" e implementata con un gestore che ha fatto un po 'giocherellare. Probabilmente la funzione PDP-11 ha incoraggiato la primissima edizione del linguaggio C che fornisce la %funzione. (Hai mai notato come un segno di percentuale abbia una barra? Questo lo rende una scelta intelligente per un operatore relativo alla divisione.)

La presenza del modulo Cda sola può probabilmente spiegare la sua presenza in tutte le lingue moderne. Cha una famiglia molto ampia di discendenti ed è stato altrimenti abbastanza influente.


3
L'influenza di +1 C su quasi tutte le lingue non LISP dai primi anni '70 non può essere sopravvalutata.
Ross Patterson,

8

Molti linguaggi di programmazione hanno un operatore "residuo" che può essere usato come operatore di modulo quando entrambi gli operandi sono positivi; detto operatore viene spesso chiamato operatore "modulo", perché quello è il suo uso principale. Le lingue generalmente hanno un tale operatore perché l'hardware di divisione di molte piattaforme hardware fornisce automaticamente un residuo quando si esegue una divisione e calcolare un resto o un modulo con qualsiasi altro mezzo sarebbe molto più difficile.

Non conosco la storia del supporto hardware per la divisione firmata; molti processori hanno fornito per anni hardware che può eseguire automaticamente la divisione firmata in base alla regola che se a / b produce (q, r), allora -a / b o a / -b produrrà (-q, -r), ma Non sono sicuro dei casi d'uso in cui la divisione che utilizza quella regola è particolarmente utile. In quasi tutti i casi in cui ho usato operazioni di divisione intera o "modulo" su valori negativi, ho voluto arrotondare verso l'infinito negativo sulla divisione e un'operazione di modulo reale (tale che (a + b) / b sarebbe sempre uguale (a / b) +1 e (a + b)% b equivarrebbe sempre a% b.). Poiché gli operatori non funzionano in questo modo, è necessario testare il segno del dividendo e utilizzare un codice diverso quando " s negativo - essenzialmente negando qualsiasi beneficio derivante dall'avere un'istruzione di divisione firmata in primo luogo. Sono curioso di sapere per quali scopi il supporto della divisione firmata nell'hardware sia effettivamente utile.

Tornando alla domanda originale, l'operatore del modulo è spesso utile in situazioni in cui si suppone che determinate cose accadano su base periodica, sia nello spazio (ad es. Coordinate grafiche) che nel tempo. Ad esempio, se si desidera che un evento si verifichi ogni 15 secondi, il tempo fino al prossimo evento sarà 15 - ((time_now - time_of_an_occurrence)% 15), supponendo che time_of_an_occurrencenon sia maggiore ditime_now . Se time_of_an_occurrencefosse maggiore di time_now, un operatore di modulo potrebbe continuare a utilizzare la stessa formula a condizione che la sottrazione non trabocchi, ma l'operatore residuo richiederà una formula diversa.


3
Per questo motivo, Haskell ha due operatori: remper il resto e modper il modulo con le proprietà che descrivi.
Ingo,

@Complicatedseebio: Ciò che è particolarmente divertente è che viene spesso chiamato l'operatore del modulo perché è generalmente utilizzato per calcolare il modulo, anche quando ciò richiede un codice simile m = number % base; if (m < 0) m+=base;. Non so di aver mai visto alcun codice che ha beneficiato dell'operatore rimanente q = n/d; if (n%d < 0) q+=1;diventato negativo, tranne forse , che potrebbe comunque essere scritto meglio in altri modi.
supercat

3

Il modulo è strettamente correlato alla teoria dei gruppi e degli anelli, che sono teorie matematiche fondamentali.

L'esponenziazione è solo la terza operazione nella sequenza aggiunta, moltiplicazione, esponenziazione, tetrazione (e questa è una sequenza infinita). Diventa importante soprattutto con numeri complessi, che sono più rari nell'aritmetica del computer. Una particolare esponenziazione è supportata esplicitamente, tuttavia: 2 n è comunemente scritto come 1<<n, poiché i computer sono piuttosto binari.

Il pavimento e il soffitto sono davvero rari a confronto: si applicano solo durante la conversione da ℝ a ℤ. (virgola mobile a intero). Allo stesso modo, absè associato a una mappatura da ℤ a ℕ


ℤ sono numeri interi (e ℕ è un sottoinsieme di numeri interi), devi indicare da ℝ a ℤ.
Joni,

@Joni: due esempi misti, risolti.
MSalters il

0

Ci dispiace, ma a rischio di trasformarlo in un gioco di "Call My Bluff", penso che la vera risposta a questa domanda sia abbastanza semplice:

La mod consente calcoli precisi in quantità e unità "non decimali" come date, tempo, iarde, pollici, once ecc. Nei calcoli decimali, fornisce anche un metodo per il programmatore per lavorare con una precisione numerica oltre quella fornita dall'hardware della macchina. Questo ha un numero enorme di applicazioni da molto piccole (ad es. Calcoli quantistici) a molto grandi (ad es. Scoprire nuovi numeri primi).

È importante capire che abbiamo chiamato queste cose computer per un motivo. A volte ne abbiamo bisogno per darci la risposta corretta!


Questa risposta non ha senso ... Qual è la connessione tra l'uso di "mod" e l'utilizzo di unità diverse ???
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.