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)?
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)?
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.
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. –
E 'possibile crash del programma usando mod zero o solo il risultato è sconosciuto? – Zaffy
@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
X% Y restituisce un risultato nell'intervallo [0, Y). X% 0 dovrebbe fornire un risultato maggiore o uguale a zero e inferiore a zero.
Non è vero, AFAIK il segno di 'x% y' è definito dall'implementazione se' x <0'. '-5% 2' capita di essere -1 sul mio sistema. –
Vero, le stranezze del mod. Ma ahimè è sufficiente per spiegare perché non si può mod per zero. –
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
)
Non è vero, AFAIK il segno di 'x% y' è definito dall'implementazione se' x <0'. '-5% 2' capita di essere -1 sul mio sistema. –
'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
-5% 2 = - (5% 2) in effetti. –
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
Why can ' t si sostituisce semplicemente 0 per la D esterna nella seconda equazione rendendola '(X% 0) = 0 * (w/e)' e basta chiamarla zero? –
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
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
.
è 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
@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. –
@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. –
@Mu la risposta è abbastanza diversa. Qui Petar spiega come '%' è definito matematicamente, ci spiegano perché l'errore è quello invece di qualcosa di più chiaro. – xanatos