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

17

C'è una ragione, storica o meno, perché l'operatore modulo sia 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 una "fondamentale" (non bussarla, la uso in abbondanza, ma uso anche l'esponenziazione, il valore assoluto, pavimento / soffitto o altri - sembrano altrettanto utili e necessari). Si trattava di una vecchia decisione presa in alcune specifiche che seguono Java, C, Ruby e Python o un linguaggio da cui discendono tutti? Per quanto ne so, molti dialetti Lisp includono solo +, -, / e * .

All'inizio mi sono chiesto se mod fosse particolarmente facile da implementare a livello binario (farebbe una differenza anche per quanto riguarda le decisioni su cosa dovrebbe essere un operatore "fondamentale" e cosa non dovrebbe?) ma sembra non essere . È molto più comunemente usato in programmazione di quanto penso?

    
posta Eli Rose 24.07.2013 - 00:59
fonte

4 risposte

20

Sono sicuro che è comune perché molte architetture della CPU implementano modulus come seconda uscita dell'istruzione di divisione dei numeri interi.

Non ricordo di essere presente nelle CPU degli anni '70 (6800, 8080, Z80, 1604, ecc.), ma negli anni '80, Intel 8086 e 8088, oltre al Motorola 6809 ce l'avevano.

L'architettura dell'istruzione PDP-11 specificava DIV producendo un quoziente e un resto dall'inizio (1970), sebbene le istruzioni MUL e DIV non fossero presenti nei primi progetti, ma potevano essere emulate in modo trasparente da un "istruzione non implementata trap "e implementato con un gestore che ha fatto girare il bit. Probabilmente la funzione PDP-11 ha incoraggiato la primissima edizione del linguaggio C a fornire la funzione % . (Hai mai notato in che modo un segno di percentuale ha un taglio?) Ciò lo rende una scelta intelligente per un operatore relativo alla divisione.)

La presenza del modulo in C da sola può probabilmente spiegare la sua presenza in tutte le lingue moderne. C ha una famiglia molto numerosa di discendenti e per il resto era piuttosto influente.

    
risposta data 24.07.2013 - 01:02
fonte
7

Molti linguaggi di programmazione hanno un operatore "resto" che può essere usato come operatore modulo quando entrambi gli operandi sono positivi; detto operatore è spesso chiamato l'operatore "modulo", perché questo è il suo uso principale. Le lingue in genere dispongono di un tale operatore perché l'hardware di divisione di molte piattaforme hardware fornisce automaticamente un resto quando si esegue una divisione, e il calcolo di un resto o di 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 in grado di eseguire automaticamente una divisione firmata soggetta 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 usa quella regola è particolarmente utile. In quasi tutti i casi in cui ho usato operazioni di divisione intera o di "modulo" su valori negativi, ho voluto round-verso-negativo-infinito sulla divisione e un'operazione di modulo vero (tale che (a + b) / b sempre uguale (a / b) +1 e (a + b)% b sarebbero sempre uguali a% b.). Poiché gli operatori non funzionano in questo modo, è necessario testare il segno del dividendo e utilizzare un codice diverso quando è negativo, in sostanza negando qualsiasi beneficio derivante dall'avere un'istruzione di divisione firmata in primo luogo. Sono curioso di sapere a quali scopi il supporto della divisione segnalata nell'hardware sia effettivamente utile.

Tornando alla domanda originale, l'operatore modulo è spesso utile in situazioni in cui si suppone che certe cose accadano su base periodica, nello spazio (ad esempio coordinate grafiche) o 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), assumendo time_of_an_occurrence non è maggiore di time_now . Se time_of_an_occurrence era maggiore di time_now , un operatore modulo potrebbe continuare a utilizzare la stessa formula a condizione che la sottrazione non abbia superato l'overflow, ma l'operatore restante richiederà una formula diversa.

    
risposta data 24.07.2013 - 01:32
fonte
3

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

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

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

    
risposta data 24.07.2013 - 01:43
fonte
0

Ci scusiamo, ma a rischio di trasformare questo in un gioco di "Call My Bluff" penso che la vera risposta a questa domanda sia piuttosto semplice:

Mod consente calcoli precisi in quantità e unità non decimali come date, ore, metri, pollici, once, ecc. Nei calcoli decimali, fornisce anche un metodo per il programmatore di operare su una precisione numerica oltre quella fornita dall'hardware della macchina. Questo ha un numero enorme di applicazioni dal molto piccolo (ad esempio calcoli quantistici) al molto grande (ad esempio, alla scoperta di nuovi numeri primi).

È importante capire che abbiamo chiamato queste cose computer per una ragione. A volte abbiamo bisogno di loro per darci la risposta corretta!

    
risposta data 24.07.2013 - 23:41
fonte

Leggi altre domande sui tag