Perché il modulo è diverso nei diversi linguaggi di programmazione?
Domanda
Perl
print 2 % -18;
- GT &;
-16
Tcl
puts [expr {2 % -18}]
- GT &;
wscript.echo 2 mod -18
ma VBScript
2
- GT &;
<*>Perché la differenza?
Soluzione
La risposta di Wikipedia è abbastanza utile qui.
Un breve riassunto è che qualsiasi numero intero può essere definito come
a = qn + r
dove tutte queste lettere sono numeri interi e
0 < = | r | lt &; | N |.
Quasi tutti i linguaggi di programmazione richiedono che (a / n) * n + (a% n) = a. Quindi la definizione di modulo dipenderà quasi sempre dalla definizione di divisione intera. Sono disponibili due opzioni per la divisione dei numeri interi per numeri negativi 2 / -18 = 0 o 2 / -18 = -1. A seconda di quale è vero per la tua lingua di solito cambierà l'operatore%.
Questo perché 2 = (-1) * -18 + (-16) e 2 = 0 * -18 + 2.
Per Perl la situazione è complicata. La pagina del manuale dice: " Nota che quando si usa l'intero ambito, "% " ti dà accesso diretto all'operatore del modulo come implementato dal tuo compilatore C. Questo operatore non è ben definito per gli operandi negativi, ma verrà eseguito più velocemente. & Quot; Quindi può scegliere una delle opzioni per Perl (come C) se usa l'intero è nell'ambito. Se l'uso intero non rientra nell'ambito, il manuale dice & Quot; Se $ b è negativo, allora $ a% $ b è $ a meno il multiplo più piccolo di $ b che non è inferiore a $ a (ovvero il risultato sarà inferiore o uguale a zero). quot &;
Altri suggerimenti
La pagina " Modulo operazione " di Wikipedia lo spiega abbastanza bene . Non cercherò di fare di meglio qui, poiché probabilmente farò un errore sottile ma importante.
Il problema è che puoi definire " resto " oppure " modulo " in modi diversi e lingue diverse hanno scelto opzioni diverse da implementare.
Dopo aver diviso un numero e un divisore, uno dei quali è negativo, hai almeno due modi per separarli in un quoziente e un resto, in modo tale quoziente * divisore + resto = numero: puoi arrotondare il quoziente verso infinito negativo, o verso zero.
Molte lingue ne scelgono solo una.
Non posso resistere nel sottolineare che Common Lisp offre entrambe le cose.
python, ovviamente, ti informa esplicitamente
>>> divmod(2,-18)
(-1, -16)