Я хочу сделать простой макрос с #define для возврата меньшего из двух чисел.C Макро для минимум двух чисел
Как я могу это сделать в C? Предложите некоторые идеи и посмотрите, можете ли вы сделать ее еще более запутанной.
Я хочу сделать простой макрос с #define для возврата меньшего из двух чисел.C Макро для минимум двух чисел
Как я могу это сделать в C? Предложите некоторые идеи и посмотрите, можете ли вы сделать ее еще более запутанной.
Для немного запутанным, попробуйте следующее:
#define MIN(a,b) ((((a)-(b))&0x80000000) >> 31)? (a) : (b)
В основном, это вычитает их, и смотрит на знак-бит, как 1-или-0. Если вычитание приводит к отрицательному числу, первый параметр меньше.
Предполагая, что тип 32-бит. – GManNickG
Спасибо - это то, что я искал. – VaioIsBorn
К сожалению, на самом деле это не работает даже для 32-битных целых чисел, если вы не считаете, что 2147483647 меньше -1. –
правило:
#define min(a, b) (((a) < (b)) ? (a) : (b))
Имейте в виду, это оценивает минимум в два раза, что стало причиной катастрофы в recent question.
Но почему вы хотите запутать его?
Это хранит результат в переменной и оценивает каждый аргумент только один раз. Это в основном бедных мужчин встроенная функция + декларация:
#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.
*/
Он должен быть немного запутанным - он предназначен для другого человека, который думает, что он программист-вдохновитель, вот почему. Во всяком случае, tnx. – VaioIsBorn
Руководитель, на каком языке? Если мы отправимся на C++, я уверен, что могу попытаться дать ему что-нибудь, чтобы пожарить его экспертную лапшу. Но хорошо, какие предположения мы можем сделать? Являются ли эти целые числа минимальными? Опять же, возможно, это всего лишь предыстория, чтобы обмануть меня в ответ. :) – GManNickG
«Я могу дать ему что-нибудь, чтобы пожарить его экспертную лапшу» - рад это слышать, ожидая дальнейших ответов xD. Кстати, вопрос был в том, что в классе нам нужна простая минимальная функция, поэтому я решил пойти с макросом, чтобы он выглядел больше c-ish. – VaioIsBorn
Конечно, вы можете использовать #define для этого, но почему вы хотите? Проблема с использованием #define, даже с круглыми скобками, заключается в том, что вы получаете неожиданные результаты с таким кодом (хорошо, вы на самом деле этого не делали, но это иллюстрирует проблему).
int result = min(a++, b++);
Если вы используете C++ не C, конечно же, лучше использовать функцию инлайн, которая (I) избегает оценки параметров более чем один раз, и (б) типобезопасен (вы можете даже представить версии с другие типы значений, например unsigned, double или string).
inline int min(int a, int b) { return (a < b) ? a : b; }
В C++ это должна быть функция шаблона для * любого * типа. И, конечно, нет необходимости переписывать его; есть уже один в '
Вы можете написать встроенную функцию в C99 или с расширениями компилятора ('__inline' в MSVC,' __inline__' в GNU C89). –
И, только для ада этого, пример 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_; \
})
Это не затемненные, но я думаю, что это работает для любого типа, в любом контексте, (почти см комментариев) любой аргументы и т. д .; пожалуйста, исправьте, если вы можете думать о каких-либо контрпримерах.
Это вряд ли произойдет, но это будет нарушено, если 'a' или' b' станут самими переменными с именем '_a_temp_' и' _b_temp_'. – jamesdlin
Да, я думал о склеивании на '__LINE__', но это не стоило усилий; если бы существовал только макрос '__UNIQUE__' ... –
Вы бы заслужили гораздо лучший результат, см. http://stackoverflow.com/a/3437484/2436175 Возможно, что пропустил немного объяснение причины, по которой этот безопаснее. – Antonio
Я думаю, что этот метод довольно мило:
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
Если бы я просто пытался слегка запутать это, я бы, вероятно, пойти что-то вроде:
#define min(a,b) ((a) + ((b) < (a) ? (b) - (a) : 0))
Я думаю, что решение Doynax является симпатичный, тоже. Обычные резервирования для обоих аргументов макроса оцениваются более одного раза.
Я хочу создать простой макрос с #define для возврата меньшего из двух чисел.
Я хотел бы добавить решение, когда числа являются с плавающей точкой.
Рассмотрим, когда числа с плавающей запятой и один из чисел not-a-number. Тогда результат a < b
всегда равен false
независимо от значения другого номера.
// the result is `b` when either a or b is NaN
#define min(a, b) (((a) < (b)) ? (a) : (b))
Может быть желательно, чтобы результат был следующим, где «аргументы NaN обрабатываются как отсутствующие данные». C11 Сноска # 242
a NaN | b NaN | a < b | min
-------+---------+---------+---------------
No | No | No | b
No | No | Yes | a
No | Yes | . | a
Yes | No | . | b
Yes | Yes | . | either a or b
Чтобы сделать это с помощью макроса в C будет просто обертка функция fmin()
которая supprts приведенную выше таблицу. Конечно, код обычно должен использовать функцию fmin()
.
#include <math.h>
#define my_fmin(a, b) (fmin((a), (b))
Обратите внимание, что fmin(0.0, -0.0)
может вернуться 0.0
или -0.0
. Оба они имеют равное значение.
Возможный дубликат [MIN и MAX in C] (http://stackoverflow.com/questions/3437404/min-and-max-in-c) – Antonio