|
Сделать из дефайна функцию. |
|
|
|
Jun 12 2017, 14:14
|
Профессионал
    
Группа: Участник
Сообщений: 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));} Как мне из него сделать С функцию?
|
|
|
|
|
Jun 12 2017, 14:50
|
Профессионал
    
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jun 12 2017, 14:58
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Jenya7 @ Jun 12 2017, 17:50)  так что ли . . . По-моему, не совсем. Код . . . (((typeof(x))-1) > 0 || // - проверка типа, или его кода ((typeof(divisor))-1) > 0 // - тоже (__x) > 0) Чтобы понять что должно быть - надо откопать кто-есть-ху макрос typeof() или что-оно-там-есть. Если аргументы фиксированного типа - то это все никчему.
|
|
|
|
|
Jun 12 2017, 15:05
|
Профессионал
    
Группа: Участник
Сообщений: 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;
|
|
|
|
|
Jun 13 2017, 08:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Jenya7 @ Jun 12 2017, 18:05)  я так понимаю в моем случае (unsigned int) все сводиться к return (x + (divisor / 2)) / divisor; Это можно только предположить. Исходя из названия "DIV_ROUND_CLOSEST" макрос как-то относится к делению, округлению (или его подвиду) и и еще чему-то. Как гипотеза: округление для плавающих типов в ту или иную сторону, в зависимости от знака.
|
|
|
|
|
Jun 13 2017, 10:53
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jun 13 2017, 11:49
|
Профессионал
    
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jun 13 2017, 13:53
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(ar__systems @ Jun 13 2017, 15:24)  Если непонятно, надо в гугле почитать, зачем фантазировать? В выражениях оно только для приведения типа. Я не использую GCC. Если хотите оказать содействие ТС - объясните, что означает Код ((typeof(x))-1) А именно - наличие двойных скобок и знака минус, так как в док., ссылку на которуую дал XVR я арифмет. операций не увидел
|
|
|
|
|
Jun 13 2017, 15:02
|

Профессионал
    
Группа: Свой
Сообщений: 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)); \ } \ ) Зачем что-то изобретать на ровном месте, если есть документация?!
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|