How can I write a 'clamp' / 'clip' / 'bound' macro for returning a value in a given range?

不打扰是莪最后的温柔 提交于 2019-12-18 04:11:57

问题


I often find myself writing something like

int computedValue = ...;
return MAX(0, MIN(5, computedValue));

I would like to be able to write this as a single one-line macro. It must be free of side effects, in the same way that the existing system macros MIN and MAX are, and should work for the same data types as MIN and MAX.

Can anyone show me how to turn this into a single macro?


回答1:


This is without side effects and works for any primitive number:

#define MIN(A,B)    ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
#define MAX(A,B)    ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })

#define CLAMP(x, low, high) ({\
  __typeof__(x) __x = (x); \
  __typeof__(low) __low = (low);\
  __typeof__(high) __high = (high);\
  __x > __high ? __high : (__x < __low ? __low : __x);\
  })

Can be used like so

int clampedInt = CLAMP(computedValue, 3, 7);
double clampedDouble = CLAMP(computedValue, 0.5, 1.0);

Other suggested names instead of CLAMP can be VALUE_CONSTRAINED_LOW_HIGH, BOUNDS, CLIPPED.




回答2:


Taken from this site http://developer.gnome.org/glib/2.34/glib-Standard-Macros.html#CLAMP:CAPS

#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))



回答3:


Maybe you want to try it like that:

template <class T> 
const T& clamp(const T& value, const T& low, const T& high) {
    return value < low ? low:
           value > high? high:
                         value;
}



回答4:


 #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 
 #define MIN(a, b) (((a) > (b)) ? (b) : (a))

making it in one #define directive isn't going to be very readable.




回答5:


Using just one compare operation:

static inline int clamp(int value, int min, int max) {
    return min + MIN((unsigned int)(value - min), max - min)
}


来源:https://stackoverflow.com/questions/14769603/how-can-i-write-a-clamp-clip-bound-macro-for-returning-a-value-in-a-gi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!