Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Сделать из дефайна функцию.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Jenya7
Я запутался. В Линуксе есть дефайн
Код
#define DIV_ROUND_CLOSEST(x, divisor)         \
{                                             \
    typeof(x) __x = x;                        \
    typeof(divisor) __d = divisor;            \
    (((typeof(x))-1) > 0 ||                   \
    ((typeof(divisor))-1) > 0 || (__x) > 0) ? \
    (((__x) + ((__d) / 2)) / (__d)) :         \
    (((__x) - ((__d) / 2)) / (__d));}

Как мне из него сделать С функцию?
k155la3
Цитата(Jenya7 @ Jun 12 2017, 17:14) *
. . .
Как мне из него сделать С функцию?

Загвоздка с typeof(x). IMHO. Возможно это тоже из специфичных макросов.
Тем более - в С. ОНО скорее подходит для конвертации в шаблон С++.


Jenya7
Цитата(k155la3 @ Jun 12 2017, 19:36) *
Загвоздка с typeof(x). IMHO. Возможно это тоже из специфичных макросов.
Тем более - в С. ОНО скорее подходит для конвертации в шаблон С++.

да. генерик для эмбедед не получиться. а если аргументы uint32_t ?

так что ли
Код
unsigned int Div_Round_Closest(unsigned int x, unsigned int divisor)        
{                                            
    if ( (x-1) > 0 || (divisor-1) > 0 || (x > 0))
        return (x + (divisor / 2)) / divisor;
    else      
         return (x - (divisor / 2)) / divisor;
}
k155la3
Цитата(Jenya7 @ Jun 12 2017, 17:50) *
так что ли
. . .


По-моему, не совсем.
Код
. . .
    (((typeof(x))-1) > 0 ||               //   - проверка типа, или его кода
    ((typeof(divisor))-1) > 0            //   - тоже
     (__x) > 0)

Чтобы понять что должно быть - надо откопать кто-есть-ху макрос typeof() или что-оно-там-есть.
Если аргументы фиксированного типа - то это все никчему.


Jenya7
Цитата(k155la3 @ Jun 12 2017, 19:58) *
По-моему, не совсем.
Код
. . .
    (((typeof(x))-1) > 0 ||               //   - проверка типа, или его кода
    ((typeof(divisor))-1) > 0            //   - тоже
     (__x) > 0)

Чтобы понять что должно быть - надо откопать кто-есть-ху макрос typeof() или что-оно-там-есть.
Если аргументы фиксированного типа - то это все никчему.


я так понимаю в моем случае (unsigned int) все сводиться к return (x + (divisor / 2)) / divisor;
x893
1. Посмотрите что генерирует препроцессор и сразу будет понятно, что там может быть.
2. Поиском можно найти все DIV_ROUND_CLOSEST и посмотреть какие типы аргументов используются.
3. Поставьте unsigned int в типах параметров и запустите компиляцию. Если откомпилирует без ошибок/предупреждений - значит этого хватит.

Ну и еще способов несколько гугла скажет.
k155la3
Цитата(Jenya7 @ Jun 12 2017, 18:05) *
я так понимаю в моем случае (unsigned int) все сводиться к return (x + (divisor / 2)) / divisor;

Это можно только предположить. Исходя из названия "DIV_ROUND_CLOSEST"
макрос как-то относится к делению, округлению (или его подвиду) и и еще чему-то.
Как гипотеза: округление для плавающих типов в ту или иную сторону, в зависимости от знака.

Jenya7
Цитата(k155la3 @ Jun 13 2017, 13:23) *
Это можно только предположить. Исходя из названия "DIV_ROUND_CLOSEST"
макрос как-то относится к делению, округлению (или его подвиду) и и еще чему-то.
Как гипотеза: округление для плавающих типов в ту или иную сторону, в зависимости от знака.

то есть как предроложить? тут либо (((__x) - ((__d) / 2)) / (__d)) = (x - (divisor / 2)) / divisor либо нет, какие могут быть варианты.
k155la3
Цитата(Jenya7 @ Jun 13 2017, 12:25) *
то есть как предроложить? тут либо ... либо нет, какие могут быть варианты.

Исходя из имеющейся инф-ии, непонятно, как работает typeof(x), а ОНО фигурирует в условии.

XVR
Цитата(k155la3 @ Jun 13 2017, 12:47) *
Исходя из имеющейся инф-ии, непонятно, как работает typeof(x), а ОНО фигурирует в условии.

Это абсолютно стандартное расширение gcc - http://gcc.gnu.org/onlinedocs/gcc/Typeof.html
demiurg_spb
Код
unsigned int Div_Round_Closest(unsigned int x, unsigned int divisor)
{
    return (x/(float)divisor + 0.5f);
}
- это только положительных чисел, а для отрицательных -0,5f надо.

Либо так:
Код
int divRoundClosest(const int n, const int d)
{
  return ((n < 0) ^ (d < 0)) ? ((n - d/2)/d) : ((n + d/2)/d);
}

Подробности тут:
https://stackoverflow.com/questions/2422712...d-of-truncating
Jenya7
Цитата(demiurg_spb @ Jun 13 2017, 15:53) *
Код
unsigned int Div_Round_Closest(unsigned int x, unsigned int divisor)
{
    return (x/(float)divisor + 0.5f);
}

- это только положительных чисел, а для отрицательных -0,5f надо.

спасибо. таки надо округлять. только не пойму как divisor сократился?

а. понял.
весь макрос сводиться к округлению результата.
ar__systems
Цитата(k155la3 @ Jun 13 2017, 04:47) *
Исходя из имеющейся инф-ии, непонятно, как работает typeof(x), а ОНО фигурирует в условии.

Если непонятно, надо в гугле почитать, зачем фантазировать? В выражениях оно только для приведения типа.
k155la3
Цитата(ar__systems @ Jun 13 2017, 15:24) *
Если непонятно, надо в гугле почитать, зачем фантазировать? В выражениях оно только для приведения типа.

Я не использую GCC. Если хотите оказать содействие ТС - объясните, что означает
Код
((typeof(x))-1)

А именно - наличие двойных скобок и знака минус, так как в док.,
ссылку на которуую дал XVR я арифмет. операций не увидел sad.gif

esaulenka
Цитата(k155la3 @ Jun 13 2017, 16:53) *
Я не использую GCC. Если хотите оказать содействие ТС - объясните, что означает

Гугл-то вы используете?

По словам "gcc typeof" можно найти исчерпывающее описание.
Примеры по первой же ссылке:
Код
#define pointer(T)  typeof(T *)
#define array(T, N) typeof(T [N])


((typeof(x))-1)
означает "привести минус единицу к типу исходного аргумента". Там они дальше проверяют, положительное это число (что, очевидно, будет если икс - беззнаковый тип), или отрицательное (для знакового икса).


Более того, можно вбить в гугл слово "DIV_ROUND_CLOSEST". Также по ПЕРВОЙ же ссылке есть исходный заголовок, в котором есть подробный комментарий.
Код
/*
* Divide positive or negative dividend by positive or negative divisor
* and round to closest integer. Result is undefined for negative
* divisors if he dividend variable type is unsigned and for negative
* dividends if the divisor variable type is unsigned.
*/
#define DIV_ROUND_CLOSEST(x, divisor)(            \
{                            \
    typeof(x) __x = x;                \
    typeof(divisor) __d = divisor;            \
    (((typeof(x))-1) > 0 ||                \
     ((typeof(divisor))-1) > 0 ||            \
     (((__x) > 0) == ((__d) > 0))) ?        \
        (((__x) + ((__d) / 2)) / (__d)) :    \
        (((__x) - ((__d) / 2)) / (__d));    \
}                            \
)


Зачем что-то изобретать на ровном месте, если есть документация?!
k155la3
Цитата(esaulenka @ Jun 13 2017, 18:02) *
(1) Гугл-то вы используете?
(2)((typeof(x))-1)
(3)Зачем что-то изобретать на ровном месте, если есть документация?!

(1) Да.
(2) (?)
Код
float x;
(
    ( ( typeof(x) ) -1 ) > 0
) == (TRUE / FALSE ) (?)

(3) Исходя из постулатов (1)+(3) надо всех вопрошающих посылать в Google.
Примеры приведенные Вами я видел, но не стал цитировать.
ViKo
Когда такое возможно?
(typeof(x))-1) > 0
megajohn
Цитата(ViKo @ Jun 14 2017, 09:49) *
Когда такое возможно?
(typeof(x))-1) > 0


здрасьте
uint32_t i = 0;
i--;
тогда i = 0xFFFFFFF;
ViKo
То есть, так проверяется, что x беззнакового типа?
sigmaN
На С++ я бы начал с такой реализации. WARNING! Не тестировалось! Но вроде должно работать....
Код
template <typename T, typename V>
T DIV_ROUND_CLOSEST_CPP(T x, V divisor)
{
    return ( T(1) > 0 || V(-1) > 0 || x > 0) ?
    ((x + (divisor / 2)) / divisor):
    ((x - (divisor / 2)) / divisor);
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.