Note that there are some explanatory texts on larger screens.

plurals
  1. POTemplatized branchless int max/min function
    text
    copied!<p>I'm trying to write a branchless function to return the MAX or MIN of two integers without resorting to if (or ?:). Using <a href="https://stackoverflow.com/questions/227383/how-do-i-programmatically-return-the-max-of-two-integers-without">the usual technique</a> I can do this easily enough for a given word size:</p> <pre><code>inline int32 imax( int32 a, int32 b ) { // signed for arithmetic shift int32 mask = a - b; // mask &lt; 0 means MSB is 1. return a + ( ( b - a ) &amp; ( mask &gt;&gt; 31 ) ); } </code></pre> <p>Now, assuming <a href="http://en.wikipedia.org/wiki/For_arguing" rel="nofollow noreferrer">arguendo</a> that I really am writing the kind of application on the kind of in-order processor where this is necessary, my question is whether there is a way to use C++ templates to generalize this to all sizes of int. </p> <p>The <strong>>>31</strong> step only works for int32s, of course, and while I could copy out overloads on the function for int8, int16, and int64, it seems like I should use a template function instead. But how do I get the size of a template argument in <em>bits</em>? </p> <p>Is there a better way to do it than this? Can I force the mask T to be signed? If T is unsigned the mask-shift step won't work (because it'll be a logical rather than arithmetic shift).</p> <pre><code>template&lt; typename T &gt; inline T imax( T a, T b ) { // how can I force this T to be signed? T mask = a - b; // I hope the compiler turns the math below into an immediate constant! mask = mask &gt;&gt; ( (sizeof(T) * 8) - 1 ); return a + ( ( b - a ) &amp; mask ); } </code></pre> <p>And, having done the above, can I prevent it from being used for anything but an integer type (eg, no floats or classes)?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload