C Macro for at least two numbers

I want to make a simple C # define macro to return the smaller of two numbers.

How can I do this in C? Suggest some ideas and see if you can make it even more confusing.

+4
source share
7 answers

To get a little confused, try the following:

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

Basically, he subtracts them and looks at the signed bit as 1-or-0. If subtraction leads to a negative number, the first parameter is less.

-6
source

Usually:

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

Be careful, this is rated at least twice, which has caused a disaster in a recent issue .

But why do you want to confuse him?


This stores the result in a variable and evaluates each argument only once. This is basically the built-in + man function:

 #define min(t, x, a, b) \ tx; \ { \ 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 as:

 min(int, x, 3, 4) /* x is an int, equal to 3 Just like doing: int x = min(3, 4); Without double evaluation. */ 
+11
source

And to hell with this, an GNU C example:

 #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_; \ }) 

This is not obfuscation, but I think it works for any type, in any context, for (almost, see comments) any arguments, etc .; please correct if you can think of any counterexamples.

+4
source

Of course, you can use #define for this, but why do you need it? The problem with using #define, even with parentheses, is that you get unexpected results with this code (well, you really didn't, but that illustrates the problem).

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

If you use C ++ rather than C, then it is better to use a built-in function that (i) avoids evaluating parameters more than once and (ii) is type safe (you can even provide versions using other types of values, for example unsigned, double or string).

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

I think this method is pretty cute:

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

+3
source

If I was just trying to confuse this, I would probably go with something like:

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

I think the Doynax solution is pretty nice too. Regular reservations for both macro arguments are evaluated more than once.

0
source

I want to make a simple C # define macro to return the smaller of two numbers.

I wanted to add a solution when numbers are floating point.


Consider when numbers are floating point numbers and one of the numbers is not-a-number . Then the result a < b always false regardless of the value of another number.

 // the result is `b` when either a or b is NaN #define min(a, b) (((a) < (b)) ? (a) : (b)) 

It may be desirable for the result to be as shown below, where β€œNaN arguments are treated as missing data”. C11 Footnote # 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 this with a macro in C, you can simply wrap the fmin() function, which will exceed the table above. Of course, code should usually use the fmin() function directly.

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

Note that fmin(0.0, -0.0) can return 0.0 or -0.0 . Both of them have equal value.

0
source

Source: https://habr.com/ru/post/1304317/


All Articles