2011-09-10 21 views
48

Perché X % 0 è un'espressione non valida?Can not Mod Zero?

Ho sempre pensato che X % 0 dovrebbe essere uguale a X. Dato che non puoi dividere per zero, la risposta non dovrebbe essere naturalmente il resto, X (tutto rimasto)?

+0

@xanatos Anche a me. Ho dato l'altro +1 per bilanciare l'altro -1 ... Sospetto che sia altamente duplicato, ma poi avrebbe dovuto essere votato per essere chiuso. –

+0

@pst: possibile duplicato di [Perché si tratta di un'eccezione in virgola mobile?] (Http://stackoverflow.com/questions/1081250/why-is-this-a-floating-point-exception) ma non era esattamente facile da trovare. –

+1

@Mu la risposta è abbastanza diversa. Qui Petar spiega come '%' è definito matematicamente, ci spiegano perché l'errore è quello invece di qualcosa di più chiaro. – xanatos

risposta

33

Il C++ standard (2003) dice nel §5.6/4,

[...] Se il secondo operando/o% è pari a zero il comportamento è definito ; [...]

Cioè seguenti espressioni invocano indefinito-comportamento (UB):

X/0; //UB 
X % 0; //UB 

Si noti anche che -5 % 2 non è uguale a -(5 % 2) (come Petar sembra suggerire in il suo commento alla sua risposta). È definito dall'implementazione. Le specifiche dicono (§5.6/4),

[...] Se entrambi gli operandi sono non negativi, il resto non è negativo; in caso contrario, il segno del resto è definito dall'implementazione.

+0

Probabilmente mi propongo di "* parzialmente * implementazione definita", il segno è definito dall'implementazione ma il valore non dovrebbe essere corretto una volta scelto il segno? Ma questo è solo un pignolo. –

+0

E 'possibile crash del programma usando mod zero o solo il risultato è sconosciuto? – Zaffy

+0

@Zaffy: Poiché mod zero richiama il comportamento non definito (UB), quindi sì, è * possibile * arrestare il programma in modo anomalo con mod zero, ma è ** not ** * guranteed * per bloccare il programma. Il crash del programma è solo una delle milioni di possibilità offerte da UB. – Nawaz

1

X% Y restituisce un risultato nell'intervallo [0, Y). X% 0 dovrebbe fornire un risultato maggiore o uguale a zero e inferiore a zero.

+2

Non è vero, AFAIK il segno di 'x% y' è definito dall'implementazione se' x <0'. '-5% 2' capita di essere -1 sul mio sistema. –

+0

Vero, le stranezze del mod. Ma ahimè è sufficiente per spiegare perché non si può mod per zero. –

4

X % D è di definizione un numero 0 <= R < D, in modo tale che esiste Q in modo che

X = D*Q + R 

Quindi, se D = 0, tale numero può esiste (perché 0 <= R < 0)

+2

Non è vero, AFAIK il segno di 'x% y' è definito dall'implementazione se' x <0'. '-5% 2' capita di essere -1 sul mio sistema. –

+0

'X = D * Q + R' funziona con _any_' Q' quando 'D = 0', con' X = R' come desiderato dall'OP. È il '0 <= R <0' che è impossibile da soddisfare. La tua risposta sembra implicare che sia il contrario, anche se potrei semplicemente leggerlo male. – hammar

+0

-5% 2 = - (5% 2) in effetti. –

8

maggio vuole vedere this.

Come divisione per 0 è undefined, mod, che si basa sulla divisione, è anche undefined.


Rappresenta la divisione; è costituito dalla parte integrante e resto:

(X/D) = floor(X/D) + (X % D)/D 

riarrangiati, si ottiene:

(X % D)/D = (X/D) - floor(X/D) 
(X % D) = D * ((X/D) - floor(X/D)) 

Sostituendo 0 per D:

(X % D) = D * ((X/0) - floor(X/0)) 

Dal divisione per 0 è undefined:

(X % D) = D * (undefined - floor(undefined)) 
(X % D) = D * (undefined) 
(X % D) = undefined 
+0

Why can ' t si sostituisce semplicemente 0 per la D esterna nella seconda equazione rendendola '(X% 0) = 0 * (w/e)' e basta chiamarla zero? –

2

credo perché per ottenere il resto del X % 0 è necessario calcolare prima X/0 che produce l'infinito, e cercando di calcolare il resto di infinito non è davvero possibile.

Tuttavia, la migliore soluzione in linea con il pensiero sarebbe quello di fare qualcosa di simile

REMAIN = Y ? X % Y : X 
2

Un altro modo che potrebbe essere concettualmente facile capire il problema:

Ignorando per il momento il problema di segno argomento, a % b potrebbe essere facilmente riscritto come a - ((a/b) * b). L'espressione a/b non è definita se b è zero, quindi in tal caso deve essere presente anche l'espressione generale.

Alla fine, il modulo è effettivamente un'operazione di divisione, quindi se a/b non è definito, non è irragionevole aspettarsi che sia lo a % b.

0

è possibile eludere il caso "divivion by 0" di (A% B) per il suo tipo identity float mod (a, b) per float (B) = b = 0.0, che non è definito o definito in modo diverso tra qualsiasi 2 implementazioni, per evitare errori di logica (crash del disco) a favore di errori aritmetici ...

calcolando mod([a*b],[b])==b*(a-floor(a))
instread dI
calcolo mod([a],[b])

dove [a * b] == tuo asse x , nel tempo [b] == il massimo della curva altalena (che non sarà mai raggiunta) == la prima derivata dell'oscillazione funzione

https://www.shadertoy.com/view/MslfW8

Problemi correlati