2012-10-28 5 views
7

Ho una domanda circa il codice seguente:divisione per zero - c programmazione

int main { 
double x = 0; 
double y = 0/x; 

if(y==1) {.....} 
.... 
.... 
return 0; 
} 

Quando eseguo il codice sul mio computer, non ottengo errore di runtime e vedo che y = -nan(0x8000000000000). Perché non è un errore di runtime da dividere per zero?

Inoltre, quando cambio la prima riga su int x = 0; ora c'è un errore di runtime. Qual è la differenza?

+3

@Jens: No, l'allegato F dello standard C99 prevale su questo e non si ottiene un comportamento indefinito per il punto mobile. Non tutte le implementazioni supportano l'appendice F, ma la tua e la mia fanno. –

risposta

9

Il motivo non si ottiene un'eccezione o un errore è perché per una doppia, l'infinito e NaN sono definiti (vedi IEEE floating point), ma quando si tenta lo stesso per intero, si otterrà un errore perché NaN/Infinity aren 't definito

+2

Non si ottiene sempre un errore per intero '0/0', dipende dall'implementazione. –

+0

@DietrichEpp: in particolare dipende dalla CPU. –

+0

@JanHudec: non necessariamente. –

13

Non si può fare affidamento su questo "lavoro" (vale a dire fare sempre la stessa cosa, portabilmente), è un comportamento indefinito in C per il secondo caso, e anche per il primo se la vostra implementazione non definisce __STDC_IEC_559__ (questo è, credo, raro in questi giorni).

C99, §6.5.5/5

Il risultato della/operatore è il quoziente della divisione del primo operando dalla secondo; il risultato dell'operatore% è il resto. In entrambe le operazioni, se il valore di il secondo operando è zero, il comportamento non è definito.

Il fatto che stai ricevendo un "Not a Number" in un caso e non nell'altro è che si è fatto in aritmetica in virgola mobile, dove, sulla vostra implementazione (conforme a IEEE 754 divisione da zero semantica), 0/0 dà un NaN.

Nel secondo caso, si utilizza il comportamento aritmetico intero – non definito, non è possibile prevedere cosa accadrà.

+0

Va aggiunto che il comportamento osservato è definito dalla piattaforma. Ix86 capita di implementare la divisione per zero in questo modo. –

+3

Questo è in realtà sbagliato per la maggior parte dei sistemi: C99, §F.1: "Un'implementazione che definisce' __STDC_IEC_559__' deve essere conforme alle specifiche in questo allegato.Quando è indicato un legame tra il linguaggio C e IEC 60559, è specificato lo standard IEC60559 il comportamento è adottato per riferimento, se non diversamente indicato. " §F.3 "Gli operatori' + ',' -', '*' e '/' forniscono le operazioni di aggiunta, sottrazione, moltiplicazione e divisione IEC 60559. " –

+0

@DietrichEpp: meglio ora? – Mat

4

Questo perché lo standard IEEE 754 definisce valori speciali per infinito positivo e negativo insieme a "non un numero" per valori in virgola mobile.

I tipi a virgola mobile come int non hanno definito quei valori speciali e pertanto il tempo di esecuzione viene interrotto a causa di un errore non gestito.

Questo non è specifico per C, vedrete un comportamento molto simile (se non lo stesso) in altre lingue semplicemente perché questa funzionalità è ridotta all'hardware.