реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Сделать из дефайна функцию.
Jenya7
сообщение Jun 12 2017, 14:14
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Я запутался. В Линуксе есть дефайн
Код
#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));}

Как мне из него сделать С функцию?
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 12 2017, 14:36
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



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

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


Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 12 2017, 14:50
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(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;
}


Сообщение отредактировал Jenya7 - Jun 12 2017, 14:42
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 12 2017, 14:58
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Jenya7 @ Jun 12 2017, 17:50) *
так что ли
. . .


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

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


Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 12 2017, 15:05
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



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

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


я так понимаю в моем случае (unsigned int) все сводиться к return (x + (divisor / 2)) / divisor;
Go to the top of the page
 
+Quote Post
x893
сообщение Jun 12 2017, 23:28
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



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

Ну и еще способов несколько гугла скажет.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 13 2017, 08:23
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



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

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

Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 13 2017, 09:25
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



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

то есть как предроложить? тут либо (((__x) - ((__d) / 2)) / (__d)) = (x - (divisor / 2)) / divisor либо нет, какие могут быть варианты.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 13 2017, 09:47
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Jenya7 @ Jun 13 2017, 12:25) *
то есть как предроложить? тут либо ... либо нет, какие могут быть варианты.

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

Go to the top of the page
 
+Quote Post
XVR
сообщение Jun 13 2017, 10:50
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



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

Это абсолютно стандартное расширение gcc - http://gcc.gnu.org/onlinedocs/gcc/Typeof.html
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 13 2017, 10:53
Сообщение #11


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Код
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


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 13 2017, 11:49
Сообщение #12


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(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 сократился?

а. понял.
весь макрос сводиться к округлению результата.

Сообщение отредактировал Jenya7 - Jun 13 2017, 11:59
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Jun 13 2017, 12:24
Сообщение #13


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



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

Если непонятно, надо в гугле почитать, зачем фантазировать? В выражениях оно только для приведения типа.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 13 2017, 13:53
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



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

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

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

Go to the top of the page
 
+Quote Post
esaulenka
сообщение Jun 13 2017, 15:02
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(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));    \
}                            \
)


Зачем что-то изобретать на ровном месте, если есть документация?!


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 7th July 2025 - 02:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.02473 секунд с 7
ELECTRONIX ©2004-2016