Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вычисление констант
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
SasaVitebsk
Мне необходимо, для универсальности воспользоваться формулой для вычисления константы. В описании языка Си я не нашёл некоторых моментов. Например мне надо операция возведения в степень. То есть чтобы компилятор высчитал и подставил численное выражение. Ну например.

#define NUMBRZR 8 // Число отображаемых разрядов
#define DECIMAL 10 // Тип счёта
.....
j=powl(DECIMAL,NUMBRZR)-1; // Инициализировать значения
.....

Иными словами я хочу получить "99999999" в операторе присваивания. И функция здесь конечно не причём. Это выражение вычисляется на этапе компиляции.

Как написать возведение в степень?
_Bill
Цитата(SasaVitebsk @ Oct 2 2006, 12:11) *
Мне необходимо, для универсальности воспользоваться формулой для вычисления константы. В описании языка Си я не нашёл некоторых моментов. Например мне надо операция возведения в степень. То есть чтобы компилятор высчитал и подставил численное выражение. Ну например.

#define NUMBRZR 8 // Число отображаемых разрядов
#define DECIMAL 10 // Тип счёта
.....
j=powl(DECIMAL,NUMBRZR)-1; // Инициализировать значения
.....

Иными словами я хочу получить "99999999" в операторе присваивания. И функция здесь конечно не причём. Это выражение вычисляется на этапе компиляции.

Как написать возведение в степень?

Никак. На этапе компиляции происходит только вычисление константных выражений. У компилятора нет каких либо встроенных функций. Поэтому, если Вы хотите вычислять функции при инициализации, то либо Вы это делаете вручную, либо иниализация будет выполнятся во время выполнения программы. В последнем случае компилятор будет генерировать код для вызова соответствующей функции.
SasaVitebsk
Цитата(_Bill @ Oct 2 2006, 12:32) *
Никак. На этапе компиляции происходит только вычисление константных выражений. У компилятора нет каких либо встроенных функций. Поэтому, если Вы хотите вычислять функции при инициализации, то либо Вы это делаете вручную, либо иниализация будет выполнятся во время выполнения программы. В последнем случае компилятор будет генерировать код для вызова соответствующей функции.


Это приятно. У меня был ассемблер х51. Так вот он это умел делать. А на AVR Studio столкнулся с потерей точности. Надо формулу правильно писать. А то сначала поделит (отбросит лишнее) потом умножит, - ну и привет. smile.gif Как правило компиляторы PC поступаю правильно. То есть определяют если выражение константное, то сразу подставляют его значение.
dxp
Цитата(SasaVitebsk @ Oct 2 2006, 22:48) *
Цитата(_Bill @ Oct 2 2006, 12:32) *

Никак. На этапе компиляции происходит только вычисление константных выражений. У компилятора нет каких либо встроенных функций. Поэтому, если Вы хотите вычислять функции при инициализации, то либо Вы это делаете вручную, либо иниализация будет выполнятся во время выполнения программы. В последнем случае компилятор будет генерировать код для вызова соответствующей функции.


Это приятно. У меня был ассемблер х51. Так вот он это умел делать.

Это частные особенности того ассемблера. По Стандарту С/С++ компилятор не обязан рассчитывать такие выражения.

Цитата(SasaVitebsk @ Oct 2 2006, 22:48) *
А на AVR Studio столкнулся с потерей точности. Надо формулу правильно писать. А то сначала поделит (отбросит лишнее) потом умножит, - ну и привет. smile.gif

Это Вы, наверное, препроцессор имеете в виду? Он - да, на этапе компиляции рассчитывает. Но только в целых числах и только в 32-х битах. Часто этого оказывается достаточно. Только препроцессор не константы инициализирует, а макросы. А с константами уже работает компилятор. Но это уже не следующем этапе. И вот компилятор ничего вычислять на этапе компиляции не обязан. Максимум он может прооптимизировать инициализатор, если там не используются, например, функции типа синуса или логарифма.

Цитата(SasaVitebsk @ Oct 2 2006, 22:48) *
Как правило компиляторы PC поступаю правильно. То есть определяют если выражение константное, то сразу подставляют его значение.

Компиляторы PC делают это на рантайме (при загрузке программы), как и всякие другие компиляторы С/С++. Просто рантайм у PC намного дешевле, чем у МК, поэтому там у Вас вопросов нет. smile.gif

Универсальным способом решить этот вопрос можно так: вычислять значение констатны внешними инструментами и подставлять значение при сборке через ключ -D. Тогда и вычисление гарантировано будет происходить на этапе сборки, и вопросы сложности выражения и точности вычислений решаются независимо от возможностей препроцессора и компилятора.
IgorKossak
Цитата(dxp @ Oct 3 2006, 06:35) *
Универсальным способом решить этот вопрос можно так: вычислять значение констатны внешними инструментами ...

Например, бесплатным wx-devcpp.
_Bill
Цитата(dxp @ Oct 3 2006, 06:35) *
Цитата(SasaVitebsk @ Oct 2 2006, 22:48) *

Это приятно. У меня был ассемблер х51. Так вот он это умел делать.

Это частные особенности того ассемблера. По Стандарту С/С++ компилятор не обязан рассчитывать такие выражения.

Цитата(SasaVitebsk @ Oct 2 2006, 22:48) *
А на AVR Studio столкнулся с потерей точности. Надо формулу правильно писать. А то сначала поделит (отбросит лишнее) потом умножит, - ну и привет. smile.gif

Это Вы, наверное, препроцессор имеете в виду? Он - да, на этапе компиляции рассчитывает. Но только в целых числах и только в 32-х битах. Часто этого оказывается достаточно. Только препроцессор не константы инициализирует, а макросы. А с константами уже работает компилятор. Но это уже не следующем этапе. И вот компилятор ничего вычислять на этапе компиляции не обязан. Максимум он может прооптимизировать инициализатор, если там не используются, например, функции типа синуса или логарифма.

Цитата(SasaVitebsk @ Oct 2 2006, 22:48) *
Как правило компиляторы PC поступаю правильно. То есть определяют если выражение константное, то сразу подставляют его значение.

Компиляторы PC делают это на рантайме (при загрузке программы), как и всякие другие компиляторы С/С++. Просто рантайм у PC намного дешевле, чем у МК, поэтому там у Вас вопросов нет. smile.gif

Если быть точным, то препроцессор не производит каких-либо вычислений. Функцией препроцессора является простая замена одного фрагмента текста на другой. Все вычисления делаются компилятором.
И, опять же, следует иметь в виду, что вычисления производятся с фиксированной точкой (если не указано явно), и все константы имеют тип int. Можно явным образом определить константы как unsigned, long или float.
Если производятся вычисления констант целого типа, то нужно выбирать порядок вычисления таким образом, чтобы потеря точности была минимальной. Т.е. при выполнении операции деления следует стремится к тому, чтобы делимое было как можно больше, а делитель был как можно меньше.
IgorKossak
В теме имелось в виду не то, кто чем и как занимается (компилятор или препроцессор), а как вычислить константу при помощи сложной формулы, содержащей функции, на С.
Так вот ответ - никак. Ибо вместо желаемой подстановки константного значения будет вызываться функция. В плане вычисления констант компилятор С достаточно беден. Это не FORTH, где такие вычисления возможны.
Варианты обходных манёвров здесь уже приводились.
SasaVitebsk
Цитата(IgorKossak @ Oct 3 2006, 12:48) *
В теме имелось в виду не то, кто чем и как занимается (компилятор или препроцессор), а как вычислить константу при помощи сложной формулы, содержащей функции, на С.
Так вот ответ - никак. Ибо вместо желаемой подстановки константного значения будет вызываться функция. В плане вычисления констант компилятор С достаточно беден. Это не FORTH, где такие вычисления возможны.
Варианты обходных манёвров здесь уже приводились.


Тем не менее спасибо всем. Мне было очень интересно узнать данные подробности. Это даёт некоторое понимание происходящего. Я уже понял что препроцессор просто подставляет (понятно из ошибок). Но мне кажется (хотя вопрос и риторический) что не правильно вставлять формулу в код программы, если её значение можно сразу вычислить на этапе компиляции. О какой после этого оптимизации можно говорить. По-моему где то читал, что всётаки какие-то из компиляторов так и поступают. А может мне приснилось. smile.gif
Ну чтож, раз мы не можем повлиять на процесс, то надо принять его как должное. smile.gif
_Bill
Цитата(SasaVitebsk @ Oct 3 2006, 13:18) *
Тем не менее спасибо всем. Мне было очень интересно узнать данные подробности. Это даёт некоторое понимание происходящего. Я уже понял что препроцессор просто подставляет (понятно из ошибок). Но мне кажется (хотя вопрос и риторический) что не правильно вставлять формулу в код программы, если её значение можно сразу вычислить на этапе компиляции. О какой после этого оптимизации можно говорить. По-моему где то читал, что всётаки какие-то из компиляторов так и поступают. А может мне приснилось. smile.gif
Ну чтож, раз мы не можем повлиять на процесс, то надо принять его как должное. smile.gif

Все дело в том, что идентификатор функции (или переменной) может быть выбран программистом произвольно, и в общем случае компилятор не обязан знать назначение этой функции и ее расположение (в библиотеке исполнюящей системы (run time library), или в каком-либо программном модуле проекта). Здесь программисту предоставлена полная свобода в выборе идентификаторов. Соответственно, свобода компилятора получается крайне ограниченной. Поэтому никаких вычислений значений каких-либо функций компилятором не производится.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.