C 宏,求两个数中的最小值
我想用 #define 创建一个简单的宏来返回两个数字中较小的一个。
我怎样才能在 C 中做到这一点?提出一些想法,看看是否可以让它变得更加混乱。
I want to make a simple macro with #define for returning the smaller of two numbers.
How can i do this in C ? Suggest some ideas, and see if you can make it more obfuscated too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
通常:
请注意,这会评估最小值两次,这是 中发生灾难的原因最近的问题。
但你为什么要混淆它呢?
该函数将结果存储在变量中,并且仅对每个参数求值一次。它基本上是一个穷人的内联函数+声明:
使用它如下:
Typically:
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:
Use it like:
而且,只是为了它的地狱,一个 GNU C 示例:
它没有混淆,但我认为这适用于任何类型、任何上下文、(几乎,请参阅注释)任何参数等;如果您能想到任何反例,请纠正。
And, just for the hell of it, a GNU C example:
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.
当然,您可以为此使用#define,但为什么要这样做呢?使用 #define 的问题是,即使使用括号,您也会使用这样的代码得到意外的结果(好吧,您实际上不会这样做,但它说明了问题)。
如果您使用的是 C++ 而不是 C,那么使用内联函数肯定更好,它 (i) 避免多次评估参数,并且 (ii) 是类型安全的(您甚至可以提供采用其他类型值的版本,例如无符号、双精度或字符串)。
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).
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).
我认为这个方法相当可爱:
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
I think this method is rather cute:
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
我想在数字为浮点时添加解决方案。
考虑一下当数字是浮点数并且其中一个数字是非数字时。那么
a <的结果是无论另一个数字的值如何,b
始终为false
。可能希望结果如下所示,其中“NaN 参数被视为缺失数据”。 C11 脚注 #242
要使用 C 中的宏来执行此操作,只需包装支持上表的
fmin()
函数。当然,代码通常应该直接使用fmin()
函数。请注意,
fmin(0.0, -0.0)
可能返回0.0
或-0.0
。它们都有相同的价值。I wanted to add a solution when the numbers are floating point.
Consider when the numbers are floating point numbers and one of the numbers is not-a-number. Then the result of
a < b
is alwaysfalse
regardless of the value of the other number.It can be desirable that the result is as below where "NaN arguments are treated as missing data". C11 Footnote #242
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 thefmin()
function directly.Note that
fmin(0.0, -0.0)
may return0.0
or-0.0
. They both have equal value.如果我只是想稍微混淆一下这一点,我可能会选择这样的内容:
我认为 Doynax 的解决方案也非常可爱。对于多次评估宏参数的通常保留。
If I were just trying to lightly obfuscate this I would probably go with something like:
I think Doynax's solution is pretty cute, too. Usual reservations for both about macro arguments being evaluated more than once.
对于稍微混淆的情况,请尝试以下操作:
基本上,它将它们相减,并将符号位视为 1 或 0。
如果减法结果为负数,则第一个参数较小。
For slightly obfuscated, try this:
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.