Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: проблема с вычислениями
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
ARV
я в шоке!
пишу:
Код
#define MAX_PHASE    9500UL
#define TDIV        8
#define CONCAT(x,y)    x ## y
#define DIVISOR(x)    CONCAT(TIMER_CLK_DIV_,x)
#define PRESCALER    DIVISOR(TDIV)
#define MAX_OCR        (((F_CPU * (MAX_PHASE/TDIV) / 1000000)))
#define TCNT_INIT        ((UINT16_MAX + 1UL)- MAX_OCR)

вроде бы все верно (на странно расставленные скобки в MAX_OCR не обращайте внимания - это я от безысходности расставлял их). однако следующая строка
Код
    printf_P(PSTR("SI:%u;%u;%u\n"),200,MAX_OCR,TCNT_INIT);
выводит в консоль
Цитата
SI:200;242;65294

ума не приложу, в чем дело! F_CPU у меня 11059200UL, ожидаю, что MAX_OCR будет тринадцать тысяч с хвостиком - ан нет sad.gif

что не так?!
dimka76
Код
#define CONCAT(x,y)      (x ## y)
ARV
Цитата(dimka76 @ Jul 22 2010, 12:27) *
Код
#define CONCAT(x,y)      (x ## y)

и что?

ничего не понимаю... понятно, что происходит переполнение вычислений, НО ПОЧЕМУ? эффект сохраняется даже если я делаю так:(F_CPU * MAX_PHASE / TDIV / 1000000ULL) то есть делаю константу 1000000 типа unsigned long long - по идее ведь все вычисления теперь должны вестись в размерах этого типа и никакого переполнения быть не может... зато вот так все работает верно:(F_CPU / TDIV /1000 * MAX_PHASE / 1000) и вот так тоже работает ((unsigned long long)F_CPU / TDIV * MAX_PHASE / 1000000UL)

че за хрень?
Непомнящий Евгений
Цитата(ARV @ Jul 22 2010, 12:20) *
Код
#define MAX_PHASE    9500UL
#define TDIV        8
#define CONCAT(x,y)    x ## y
#define DIVISOR(x)    CONCAT(TIMER_CLK_DIV_,x)
#define PRESCALER    DIVISOR(TDIV)
#define MAX_OCR        (((F_CPU * (MAX_PHASE/TDIV) / 1000000)))
#define TCNT_INIT        ((UINT16_MAX + 1UL)- MAX_OCR)

вроде бы все верно (на странно расставленные скобки в MAX_OCR не обращайте внимания - это я от безысходности расставлял их). однако следующая строка
Код
    printf_P(PSTR("SI:%u;%u;%u\n"),200,MAX_OCR,TCNT_INIT);
выводит в консоль
ума не приложу, в чем дело! F_CPU у меня 11059200UL, ожидаю, что MAX_OCR будет тринадцать тысяч с хвостиком - ан нет sad.gif

что не так?!


MAX_OCR = 11059200 * (9500UL / 8) / 1000000 = 13127270400UL / 1000000
Дальше все зависит от того, что такое UL. Подозреваю, что это uint32_t, тогда 13127270400UL = 0x0E724000 и вы получаете 242 в результате...

Скорее всего поможет ULL...
ARV
и вот так тоже работает sad.gif
Код
#define MAX_PHASE        9500ULL
.........
#define MAX_OCR            (F_CPU * MAX_PHASE / TDIV / 1000000UL)
то есть получается, что если тип константы задан для числителя выражения - все вычисляется верно, а если для знаменателя - то нет sad.gif а я был уверен, что ВСЕ операнды в выражении приводятся к самому "длинному" или самому многоразрядному типу, встреченному среди них...

я не прав или это GCC подкачало?
Непомнящий Евгений
Цитата(ARV @ Jul 22 2010, 13:43) *
эффект сохраняется даже если я делаю так:(F_CPU * MAX_PHASE / TDIV / 1000000ULL) то есть делаю константу 1000000 типа unsigned long long - по идее ведь все вычисления теперь должны вестись в размерах этого типа ...

Это не так - типы приводятся в каждой операции отдельно. В размерности ULL идет только последнее деление, а предыдущие операции - в размерности UL (давай переполнение)
ARV
Цитата(Непомнящий Евгений @ Jul 22 2010, 13:51) *
Это не так - типы приводятся в каждой операции отдельно. В размерности ULL идет только последнее деление, а предыдущие операции - в размерности UL (давай переполнение)
гм... был уверен, что приведение типов операндов делается для всего выражения...
тем более для равноприоритетных операций...
Jat
Цитата(ARV @ Jul 22 2010, 15:20) *
я в шоке!
что не так?!


Почему? Что написано, то и получено!

Код
printf_P(PSTR("SI:%u;%u;%u\n"),200,MAX_OCR,TCNT_INIT);


Попробуй так

Код
printf_P(PSTR("SI:%u;%ul;%ul\n"),200,(unsigned long)MAX_OCR,(unsigned long)TCNT_INIT);
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.