What's the best way to define a between macro, which is type generic (char,int,long) which will return true if a number is between to other numbers inputted. I'm tried to google it, but I didn't find anything.
Edit: The order of the two boundaries given shouldn't matter. so it can be more general.
If you do something like:
#define BETWEEN(a, b, c) (((a) >= (b)) && ((a) <= (c)))
you are going to have problem with the double evaluation of a
. Think what would happens if you do that with a functions that has side effects...
you should instead do something like:
#define BETWEEN(a, b, c) ({ __typeof__ (a) __a = (a); ((__a) >= (b) && ((__a) <= (c)) })
(edited because the result should not depend of the order of b and c):
#define BETWEEN(a, b, c) \
({ __typeof__ (a) __a = (a);\
__typeof__ (b) __b = (b);\
__typeof__ (c) __c = (c);\
(__a >= __b && __a <= __c)||\
(__a >= __c && __a <= __b)})
Firstly, don't use macros for things like this - use functions (possibly inline).
Secondly, if you must use macros, then what's wrong with eg
#define BETWEEN(x, x_min, x_max) ((x) > (x_min) && (x) < (x_max))
?
As per your subsequent edit, if you don't know the ordering of x_min
and x_max
then you could do this:
#define BETWEEN2(x, x0, x1) (BETWEEN((x), (x0), (x1)) || \
BETWEEN((x), (x1), (x0)))
The usual caveats about macros and side-effects etc apply. Edit: removed space between macro & arguments for compilation
If all types are the same, how about:
/* Check if 'a' is between 'b' and 'c') */
#define BETWEEN(a, b, c) (((a) >= (b)) && ((a) <= (c)))
Note that if the types of a
, b
and c
above are different, the implicit type conversions of C might make it wrong. Especially if you mix signed and unsigned numbers.
If I understand correctly, you will need 3 numbers, the upper limit, the lower limit and the number you're checking, so I would do it like this:
#define BETWEEN(up, low, n) ((n) <= (up) && (n) >= (low))
This assumes the between is inclusive of the upper and lower limits, otherwise:
#define BETWEEN(up, low, n) ((n) < (up) && (n) > (low))
+1: A not-so-trivial question, since it involves the problem of the evaluation of macro parameters. The naive solution would be
#define BETWEEN(x,l1,l2) (((x) >= (l1)) && ((x) <= (l2)))
but "x" is evaluated twice, so there may be problems if the expression has side effects. Let's try something smarter:
#define BETWEEN(x,l1,l2) (((unsigned long)((x)-(l1))) <= (l2))
Very very tricky and not so clean, but...
#define BETWEEN_MIN(a, b) ((a)<(b) ? (a) : (b))
#define BETWEEN_MAX(a, b) ((a)>(b) ? (a) : (b))
#define BETWEEN_REAL(val, lo, hi) (((lo) <= (val)) && ((val) <= (hi)))
#define BETWEEN(val, hi, lo) \
BETWEEN_REAL((val), BETWEEN_MIN((hi), (lo)), BETWEEN_MAX((hi), (lo)))
See code running: http://ideone.com/Hb1vP
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.