2012-10-28 18 views
7

Mam pytanie odnośnie następnego kodu:dzielenie przez zero - c programowania

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

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

Kiedy uruchomić kod na komputerze, mam żadnego błędu wykonawczego i widzę, że y = -nan(0x8000000000000). Dlaczego błąd runtime nie jest dzielony przez zero?

Dodatkowo, po zmianie pierwszego wiersza na int x = 0; , teraz wystąpił błąd środowiska wykonawczego. Jaka jest różnica?

+3

@Jens: Nie, załącznik F do standardu C99 przesłania to i nie otrzymujesz nieokreślonego zachowania dla zmiennoprzecinkowego. Nie wszystkie implementacje obsługują załącznik F, ale twój i mój robią. –

Odpowiedz

9

Powodem nie dostaniesz wyjątek lub błąd dlatego za pokój, nieskończoności i NaN są zdefiniowane (patrz IEEE floating point), ale podczas próby to samo dla liczby całkowitej, dostaniesz błąd, ponieważ NaN/Nieskończoność aren 't zdefiniowany

+2

Nie zawsze wystąpi błąd liczby całkowitej "0/0", zależy to od implementacji. –

+0

@DietrichEpp: W szczególności zależy to od procesora. –

+0

@JanHudec: Niekoniecznie. –

13

Nie można polegać na tym "pracy" (to znaczy robienie tego samego cały czas, przenośnie) w ogóle, to niezdefiniowane zachowanie w C dla drugiego przypadku, a także dla pierwszego, jeśli twoja implementacja nie definiuje __STDC_IEC_559__ (jest to, jak sądzę, rzadkie w dzisiejszych czasach).

C99 §6.5.5/5

Wynik/operatora stanowi iloraz z podziału pierwszego argumentu przez sekund; wynik operatora% jest resztą. W obu operacjach, jeśli wartość drugi operand wynosi zero, zachowanie jest niezdefiniowane.

Fakt dostajesz „Not a Number” w jednym przypadku, a nie w innych jest to, że odbywa się to w arytmetyki zmiennoprzecinkowej, gdzie od implementacji (zgodnego ze standardem IEEE 754 dywizji przez zero semantyki), 0/0 daje NaN.

W drugim przypadku używamy niezdefiniowanego zachowania arytmetycznego z liczb całkowitych –, nie można przewidzieć, co się stanie.

+0

Należy dodać, że obserwowane zachowanie jest definiowane przez platformę. Ix86 zdaje się implementować dzielenie przez zero w ten sposób. –

+3

W przypadku większości systemów jest to nieprawidłowe: C99, §F.1: "Implementacja, która definiuje parametr" __STDC_IEC_559__ ", powinna być zgodna ze specyfikacjami podanymi w tym załączniku. W przypadku wskazania powiązania między językiem C a IEC 60559, specyfikacja IEC60559 zachowanie jest przyjęte przez odniesienie, chyba że zaznaczono inaczej. " §FA.3 "Operatory' +', '-',' * 'i'/'zapewniają operację dodawania, odejmowania, mnożenia i dzielenia IEC 60559." –

+0

@DietrichEpp: lepiej teraz? – Mat

4

To dlatego, że standard IEEE 754 definiuje specjalne wartości dodatniej i ujemnej nieskończoności wraz z "nie liczbą" dla wartości zmiennoprzecinkowych.

Nie zmiennoprzecinkowe typy, takie jak int, nie mają zdefiniowanych tych specjalnych wartości i dlatego czas działania jest kończony z powodu błędu, który nie został obsłużony.

To nie jest specyficzne dla C, zobaczysz bardzo podobne (jeśli nie to samo) zachowanie w innych językach, po prostu dlatego, że ta funkcjonalność zależy od sprzętu.