C Макрос для минимума двух чисел

Я хочу сделать простой макрос с #define для возврата меньших из двух чисел.

Как я могу сделать это в C? Предложите некоторые идеи и посмотрите, можно ли сделать это более запутываемым также.

5
задан a3f 31 March 2015 в 02:12
поделиться

6 ответов

Для слегка запутанных попробуйте следующее:

#define MIN(a,b)  ((((a)-(b))&0x80000000) >> 31)? (a) : (b)

Обычно он вычитает их и рассматривает знаковый бит как 1 или 0. Если в результате вычитания получается отрицательное число, первое параметр меньше.

-7
ответ дан 18 December 2019 в 09:49
поделиться

Обычно:

#define min(a, b) (((a) < (b)) ? (a) : (b))

Имейте в виду, что минимальная оценка выполняется дважды, что и было причиной катастрофы в недавнем вопросе .

Но зачем вам его запутывать?


Он сохраняет результат в переменной и оценивает каждый аргумент только один раз. По сути, это встроенная функция для бедняков + объявление:

#define min(t, x, a, b) \
            t x; \
            { \
                t _this_is_a_unique_name_dont_use_it_plz_0_ = a; \
                t _this_is_a_unique_name_dont_use_it_plz_1_ = b; \
                x = _this_is_a_unique_name_dont_use_it_plz_0_ < \  
                    _this_is_a_unique_name_dont_use_it_plz_1_ ? \
                    _this_is_a_unique_name_dont_use_it_plz_0_ : \  
                    _this_is_a_unique_name_dont_use_it_plz_1_ ; \
            }

Используйте это как:

min(int, x, 3, 4)
/* x is an int, equal to 3
  Just like doing:

  int x = min(3, 4);

  Without double evaluation.
*/
12
ответ дан 18 December 2019 в 09:49
поделиться

Конечно, вы можете используйте для этого #define, но зачем вам это нужно? Проблема с использованием #define, даже с круглыми скобками, заключается в том, что вы получаете неожиданные результаты с таким кодом (хорошо, на самом деле вы бы этого не сделали, но это иллюстрирует проблему).

int result = min(a++, b++);

Если вы используете C ++, а не C, безусловно, лучше использовать встроенную функцию, которая (i) избегает оценки параметров более одного раза и (ii) безопасна по типу (вы даже можете предоставить версии, принимающие другие типы значений , например беззнаковое, двойное или строковое).

inline int min(int a, int b) { return (a < b) ? a : b; }
3
ответ дан 18 December 2019 в 09:49
поделиться

Мне кажется этот метод довольно симпатичным:

#define min (a, b) (((a) + (b) - fabs ((a) - (b))) * 0.5)

3
ответ дан 18 December 2019 в 09:49
поделиться

И, просто для примера, пример на GNU C:

#define MAX(a,b) ({ \
    typeof(a) _a_temp_; \
    typeof(b) _b_temp_; \
    _a_temp_ = (a); \
    _b_temp_ = (b); \
    _a_temp_ = _a_temp_ < _b_temp_ ? _b_temp_ : _a_temp_; \
    })

Он не обфусцирован, но я думаю, что это работает для любого типа, в любом контексте, на (почти, см. комментарии) любых аргументах и т.д.; пожалуйста, поправьте, если сможете придумать контрпримеры.

5
ответ дан 18 December 2019 в 09:49
поделиться

Если бы я просто пытался слегка затушевать это, я бы, вероятно, выбрал что-то вроде:

#define min(a,b) ((a) + ((b) < (a) ? (b) - (a) : 0))

Я думаю, что решение Дойнакса тоже довольно симпатично. Обычные оговорки для обоих по поводу того, что аргументы макроса оцениваются более одного раза.

0
ответ дан 18 December 2019 в 09:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: