C语言 最少两个数字的 C 宏
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2458723/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C Macro for minimum of two numbers
提问by VaioIsBorn
I want to make a simple macro with #define for returning the smaller of two numbers.
我想用 #define 制作一个简单的宏来返回两个数字中较小的一个。
How can i do this in C ? Suggest some ideas, and see if you can make it more obfuscated too.
我怎样才能在 C 中做到这一点?提出一些想法,看看你是否也可以让它更加模糊。
采纳答案by abelenky
For slightly obfuscated, try this:
对于稍微混淆,试试这个:
#define MIN(a,b) ((((a)-(b))&0x80000000) >> 31)? (a) : (b)
Basically, it subtracts them, and looks at the sign-bit as a 1-or-0. If the subtraction results in a negative number, the first parameter is smaller.
基本上,它减去它们,并将符号位视为 1 或 0。如果减法结果为负数,则第一个参数较小。
回答by GManNickG
Typically:
通常:
#define min(a, b) (((a) < (b)) ? (a) : (b))
Be warned this evaluates the minimum twice, which was the reason for disaster in a recent question.
请注意,这会评估最小值两次,这是最近问题中发生灾难的原因。
But why would you want to obfuscate it?
但是你为什么要混淆它呢?
This one stores the result in a variable, and only evaluates each argument once. It's basically a poor-mans inline function + declaration:
这个将结果存储在一个变量中,并且只对每个参数求值一次。它基本上是一个穷人的内联函数+声明:
#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_ ; \
}
Use it like:
像这样使用它:
min(int, x, 3, 4)
/* x is an int, equal to 3
Just like doing:
int x = min(3, 4);
Without double evaluation.
*/
回答by David X
And, just for the hell of it, a GNU C example:
而且,只是为了它的地狱,一个 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_; \
})
It's not obfuscated, but I think this works for any type, in any context, on (almost, see comments) any arguments, etc; please correct if you can think of any counterexamples.
它没有被混淆,但我认为这适用于任何类型、任何上下文、(几乎,见评论)任何参数等;如果您能想到任何反例,请更正。
回答by doynax
I think this method is rather cute:
我觉得这个方法比较可爱:
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
回答by Huw Walters
Sure, you can use a #define for this, but why would you want to? The problem with using #define, even with parentheses, is that you get unexpected results with code like this (okay, you wouldn't actually do this, but it illustrates the problem).
当然,您可以为此使用#define,但您为什么要这样做?使用#define 的问题,即使有括号,也是用这样的代码得到意想不到的结果(好吧,你实际上不会这样做,但它说明了问题)。
int result = min(a++, b++);
If you're using C++ not C, surely better to use an inline function, which (i) avoids evaluating the parameters more than once, and (ii) is type safe (you can even provide versions taking other types of value, like unsigned, double or string).
如果您使用的是 C++ 而不是 C,那么使用内联函数肯定更好,它 (i) 避免多次评估参数,并且 (ii) 是类型安全的(您甚至可以提供采用其他类型值的版本,例如 unsigned 、双精度或字符串)。
inline int min(int a, int b) { return (a < b) ? a : b; }
回答by chux - Reinstate Monica
I want to make a simple macro with #define for returning the smaller of two numbers.
我想用 #define 制作一个简单的宏来返回两个数字中较小的一个。
I wanted to add a solution when the numbersare floating point.
当数字是浮点数时,我想添加一个解决方案。
Consider when the numbers are floating point numbers and one of the numbers is not-a-number. Then the result of a < bis always falseregardless of the value of the other number.
考虑何时数字是浮点数并且其中一个数字不是 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))
It can be desirable that the result is as below where "NaN arguments are treated as missing data". C11 Footnote #242
可能需要结果如下,其中“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
To do so with a macro in C would simple wrap the fmin()function which supprts the above table. Of course code should normally used the fmin()function directly.
使用 C 中的宏这样做会简单地包装支持fmin()上表的函数。当然代码通常应该fmin()直接使用该函数。
#include <math.h>
#define my_fmin(a, b) (fmin((a), (b))
Note that fmin(0.0, -0.0)may return 0.0or -0.0. They both have equal value.
请注意, fmin(0.0, -0.0)可能返回0.0或-0.0。它们具有相同的价值。
回答by Stephen Canon
If I were just trying to lightly obfuscate this I would probably go with something like:
如果我只是想稍微混淆一下,我可能会采用以下方法:
#define min(a,b) ((a) + ((b) < (a) ? (b) - (a) : 0))
I think Doynax's solution is pretty cute, too. Usual reservations for both about macro arguments being evaluated more than once.
我认为 Doynax 的解决方案也很可爱。通常对宏参数被评估不止一次的保留。

