Перейти к содержанию
    

Сделать из дефайна функцию.

Я запутался. В Линуксе есть дефайн

#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));}

Как мне из него сделать С функцию?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

. . .

Как мне из него сделать С функцию?

Загвоздка с typeof(x). IMHO. Возможно это тоже из специфичных макросов.

Тем более - в С. ОНО скорее подходит для конвертации в шаблон С++.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Загвоздка с 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так что ли

. . .

 

По-моему, не совсем.

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

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

Если аргументы фиксированного типа - то это все никчему.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По-моему, не совсем.

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

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

Если аргументы фиксированного типа - то это все никчему.

 

я так понимаю в моем случае (unsigned int) все сводиться к return (x + (divisor / 2)) / divisor;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Посмотрите что генерирует препроцессор и сразу будет понятно, что там может быть.

2. Поиском можно найти все DIV_ROUND_CLOSEST и посмотреть какие типы аргументов используются.

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

 

Ну и еще способов несколько гугла скажет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я так понимаю в моем случае (unsigned int) все сводиться к return (x + (divisor / 2)) / divisor;

Это можно только предположить. Исходя из названия "DIV_ROUND_CLOSEST"

макрос как-то относится к делению, округлению (или его подвиду) и и еще чему-то.

Как гипотеза: округление для плавающих типов в ту или иную сторону, в зависимости от знака.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это можно только предположить. Исходя из названия "DIV_ROUND_CLOSEST"

макрос как-то относится к делению, округлению (или его подвиду) и и еще чему-то.

Как гипотеза: округление для плавающих типов в ту или иную сторону, в зависимости от знака.

то есть как предроложить? тут либо (((__x) - ((__d) / 2)) / (__d)) = (x - (divisor / 2)) / divisor либо нет, какие могут быть варианты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

то есть как предроложить? тут либо ... либо нет, какие могут быть варианты.

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Это абсолютно стандартное расширение gcc - http://gcc.gnu.org/onlinedocs/gcc/Typeof.html

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

unsigned int Div_Round_Closest(unsigned int x, unsigned int divisor)
{
    return (x/(float)divisor + 0.5f);
}

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

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

 

а. понял.

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

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Если непонятно, надо в гугле почитать, зачем фантазировать? В выражениях оно только для приведения типа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если непонятно, надо в гугле почитать, зачем фантазировать? В выражениях оно только для приведения типа.

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

((typeof(x))-1)

А именно - наличие двойных скобок и знака минус, так как в док.,

ссылку на которуую дал XVR я арифмет. операций не увидел :(

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не использую 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));    \
}                            \
)

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...