2014-09-06 5 views
5

Я получаю деление на ноль ошибка в этой строке:НКУ: деление на ноль

if (tim2_st_ovf < T2_PREK_250) 

Эти значения определяет, как это:

volatile uint8_t tim2_st_ovf = 0; 

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

И UINT8_MAX равна 255.

Почему я получаю это? Я рассчитал его несколько раз на калькулятор и получаю ~ 15. Кроме того, если я изменяю 1024 на 1023, он не показывает никаких ошибок.

+0

Пожалуйста, разместите http://sscce.org/ (включая функцию 'main'). – pts

ответ

7

((UINT8_MAX + 1) * 1024) может стать 0, потому что, как правило, UINT8_MAX + 1 256 и 256 * 1024 равно 0 по модулю 2 . Так что, если sizeof(int) == 2 на вашем achitecture, то вы получите 0.

На типичных современных настольных архитектур с GCC, sizeof(int) == 4, и вы не получите деление на 0.

Чтобы это исправить, заменить 1024 с 1024UL , Это будет работать, потому что unsigned long гарантированно достигнет 4294967295. (Спасибо Pascal Cuoq за это объяснение.)

+0

Удивительно, спасибо за решение и объяснение! Я соглашусь с андерсером, как только смогу. – user1806687

+0

Я бы сказал, что это подтверждается тем фактом, что '16000000' отмечен символом' UL' в следующей строке, тогда как это удобно помещается внутри 32-битного целого числа (это также означает, что 'ULL' действительно будет чрезмерным на этой платформе). – Dave

+1

'unsigned long' гарантированно доходит до' 4294967295', поэтому нет возможности заменить работу '1024' на' 1024UL'. –

Смежные вопросы