2014-09-06 15 views
5

jestem coraz dzielenie przez zero błędu na tej linii:gcc: dzielenie przez zero

if (tim2_st_ovf < T2_PREK_250) 

Wartości te określa, jak ta:

volatile uint8_t tim2_st_ovf = 0; 

#define T2_PREK_250 ((250 * (F_CPU/1000))/((UINT8_MAX + 1) * 1024)) 
#define F_CPU 16000000UL 

I UINT8_MAX wynosi 255.

Dlaczego otrzymuję to? Przeliczyłem to kilka razy na kalkulatorze i otrzymuję ~ 15. Ponadto, jeśli zmienię 1024 na 1023, nie spowoduje to żadnego błędu.

+0

Proszę napisać http://sscce.org/ (w tym funkcję 'main'). – pts

Odpowiedz

7

((UINT8_MAX + 1) * 1024) może być 0, ponieważ UINT8_MAX + 1 zwykle 256, a 256 * 1024 oznacza 0 modulo 2 . Więc jeśli sizeof(int) == 2 na swojej achitecture, następnie dostać 0.

na typowych współczesnych architektur komputerów stacjonarnych z GCC, sizeof(int) == 4 i nie dostanie dzielenie przez 0.

Aby go naprawić, wymienić 1024 z 1024UL . To zadziała, ponieważ gwarantujemy, że unsigned long osiągnie poziom 4294967295. (Dzięki Pascal Cuoq za wyjaśnienie).

+0

Niesamowite, dziękuję za rozwiązanie i wyjaśnienie! Przyjmę anwsera tak szybko, jak tylko będę mógł. – user1806687

+0

Powiedziałbym, że jest to poparte faktem, że '16000000' jest oznaczony przez' UL' w następnej linii, podczas gdy wygodnie mieściłoby się to w 32-bitowej liczbie całkowitej (to również oznacza, że ​​'ULL' byłby rzeczywiście przesadą na tej platformie). – Dave

+1

'unsigned long' ma gwarancję przejścia do' 4294967295', więc nie ma mowy, aby zastąpienie '1024'' 1024UL' mogło nie działać. –

Powiązane problemy