簡體   English   中英

C宏至少有兩個數字

[英]C Macro for minimum of two numbers

我想用#define創建一個簡單的宏來返回兩個數字中較小的一個。

我怎么能用C做這個? 提出一些想法,看看你是否可以使它更加混淆。

典型:

#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.
*/

而且,僅僅為了它的地獄,一個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_; \
    })

它沒有被混淆,但我認為這適用於任何類型,在任何情況下,(幾乎,見評論)任何參數等; 如果你能想到任何反例,請更正。

當然,你可以使用#define,但你為什么要這樣做? 使用#define(即使是括號)的問題在於,使用這樣的代碼會得到意想不到的結果(好吧,你實際上不會這樣做,但它說明了問題)。

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

如果您使用的是C ++而不是C,最好使用內聯函數,它(i)避免多次評估參數,(ii)類型安全(您甚至可以提供其他類型值的版本,如unsigned ,雙或字符串)。

inline int min(int a, int b) { return (a < b) ? a : b; }

我覺得這個方法很可愛:

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

我想用#define創建一個簡單的宏來返回兩個數字中較小的一個。

我希望在數字浮點時添加解決方案。


考慮當數字是浮點數時,其中一個數字不是數字 然后,無論其他數字的值如何, 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()函數。 當然代碼通常應該直接使用fmin()函數。

#include <math.h>
#define my_fmin(a, b) (fmin((a), (b))

請注意, fmin(0.0, -0.0)可能返回0.0-0.0 它們都具有同等價值

如果我只是試圖輕率地混淆這個,我可能會用以下的東西:

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

我認為Doynax的解決方案也非常可愛。 通常對兩個宏觀參數的預留進行評估。

稍微混淆,試試這個:

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

基本上,它會減去它們,並將符號位視為1或0。 如果減法導致負數,則第一個參數更小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM