Domanda

Sono curioso di queste lingue (Java, C ...) che ignorano definizione matematica di funzionamento del modulo.

Qual è il punto di restituzione di valori negativi in ??un funzionamento del modulo (che, per definizione, dovrebbe allways restituire un numero positivo)?

È stato utile?

Soluzione

Dubito che l'operatore resto è stato volutamente progettato per avere quelle semantica, che sono d'accordo, non sono molto utili. (Hai mai scrivere un programma di calendario che mostra i giorni della settimana la domenica, Anti-sabato, Anti-venerdì, ..., anti-Lunedi per date precedenti l'epoca?)

Piuttosto, resti negativi sono un effetto collaterale del modo divisione intera è definita.

A rem B := A - (A div B) * B

Se A div B è definito come trunc(A/B), si ottiene operatore % di C. Se A div B è definito come floor(A/B), si ottiene operatore % di Python. Altre definizioni sono possibili.

Quindi, la vera domanda è:

Perché C ++, Java, C #, ecc uso troncando divisione di interi?

Perché questo è il modo in cui C fa.

Perché l'uso C divisione troncare?

In origine, C non ha specificato come / dovrebbe gestire i numeri negativi. Ha lasciato fino all'hardware.

In pratica, ogni significativo attuazione C usato troncamento divisione, così nel 1999 questa semantica stati formalmente resi parte dello standard C.

Perché l'uso di hardware troncando divisione?

Perché è più facile (= meno costoso) per implementare in termini di divisione senza segno. Basta abs(A) div abs(B) calcolare e capovolgere il segno se (A < 0) xor (B < 0).

divisione Floored ha l'ulteriore fase di sottrarre 1 dal quoziente se il resto è diverso da zero.

Altri suggerimenti

In Java, almeno, non è un operatore modulo - è una operatore resto .

Credo che la ragione per questo essere scelto in questo modo è quello di rendere questo lavoro relazione (dai JLS):

L'operazione resto per operandi sono interi dopo promozione numerico binario (§5.6.2) produce un valore risultato tale che (a / b) * b + (% B) è uguale a. Questa identità vale anche nel caso particolare che il dividendo è il numero intero negativo di entità maggiore possibile per il tipo e il divisore è -1 (il resto è 0). Ne consegue regola che il risultato dell'operazione resto può essere negativo solo se il dividendo è negativo, e può essere positivo solo se il dividendo è positivo; Inoltre, l'entità del risultato è sempre inferiore alla grandezza del divisore.

Questa relazione eguaglianza sembra una cosa ragionevole da utilizzare come parte della definizione. Se si prende la divisione troncare verso lo zero ad essere un dato, che ti lascia con un resto negativo.

Wikipedia (il corsivo è mio):

Dati due numeri positivi, una (la dividendi) e n (il divisore), un modulo n (abbreviato come mod n) può essere pensato come resto, sulla divisione di un da n. Ad esempio, l'espressione "5 mod 4" sarebbe valutata come 1 perché 5 diviso 4 foglie resto di 1, mentre "9 mod 3" sarebbe valutato come 0 perché la divisione di 9 da 3 foglie un restante 0; non c'è nulla da sottrarre dal 9 dopo aver moltiplicato 3 volte 3. (Si noti che facendo la divisione con una calcolatrice non lo farà vi mostrerà il risultato di cui qui da questa operazione, il quoziente sarà espressa come decimale.) Quando a oppure n è negativo, Questo rompe definizione ingenui giù e linguaggi di programmazione differiscono come vengono definiti questi valori. Anche se in genere eseguita con un e n entrambi essendo interi, molti sistemi di calcolo permettono altri tipi di operandi numerici. L'intervallo di numeri per un modulo intero di n è 0 a n - 1. (n mod 1 è sempre 0; n mod 0 è indefinito, possibilmente con un conseguente "divisione per zero" errore di programmazione di computer lingue) Vedi aritmetica modulare per una convenzione più vecchio e relativo applicata in teoria dei numeri.

La maggior parte di loro non sono definite per restituire un modulo. Quello che stanno definiti per ritorno è un residuo, per cui i valori positivi e negativi sono ugualmente ragionevoli.

In C o C ++ è abbastanza ragionevole dire che dovrebbe produrre qualunque sia l'hardware sottostante produce. Che scusa / ragione non funziona altrettanto bene per Java però.

Si noti inoltre che in C89 / 90 e C ++ 98/03, il resto potrebbe essere sia positivo o negativo, a patto che i risultati di resto e divisione lavorato insieme ((a/b)*b+a%b == a). In C99 e C ++ 11, le regole state serrate così la divisione deve troncare verso lo zero, e se c'è un resto deve essere negativo.

Una ragione pragmatica per restituire un valore negativo per il modulo sarebbe che l'istruzione hardware di attuazione modulo lo fa.

Quindi norme lasciano che mal definiti, in modo che i compilatori possono fare tutto ciò che è più semplice per loro.

In nessuno degli standard C o Java è % indicato come un operatore modulo -. Anzi, restituisce il resto

È definito per restituire numeri negativi per dividendo negativi in ??modo che il (a/b)*b + a%b == a relazione vale, purché a / b è rappresentabile. Poiché l'operatore di divisione è definito per troncare verso lo zero, questa vincola il segno del resto.

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