Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The best I can come up with is this</p> <pre><code>char a, b, c; std::cin &gt;&gt; a &gt;&gt; b &gt;&gt; c; if (((b-a) | (c-a)) &amp; 0x80) { // a &gt; b || a &gt; c } </code></pre> <p>With <code>gcc -O2</code> this generates only one conditional branch</p> <pre><code>40072e: 29 c8 sub %ecx,%eax 400730: 29 ca sub %ecx,%edx 400732: 09 d0 or %edx,%eax 400734: a8 80 test $0x80,%al 400736: 74 17 je 40074f &lt;main+0x3f&gt; </code></pre> <p>This leverages the constraints of the input values, since the values cannot be greater than 26 then subtracting <code>a</code> from <code>b</code> will give you a negative value when <code>a &gt; b</code>, in two's complement you know bit <code>7</code> will be set in that case - the same applies to <code>c</code>. I then <em>OR</em> both so that bit <code>7</code> indicates whether <code>a &gt; b || a &gt; c</code>, lastly we inspect bit <code>7</code> by <em>AND</em> with 0x80 and branch on that.</p> <p><strong>Update:</strong> Out of curiosity I timed 4 different ways of coding this. To generate test data I used a simple linear congruential pseudo-random number generator. I timed it in a loop for 100 million iterations. I assumed for simplicity that if the condition is true we want to add 5 to a counter, do nothing otherwise. I timed it using <code>g++ (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)</code> on an <code>Intel Xeon X5570 @ 2.93GHz</code> using <code>-O2</code> optimization level.</p> <p>Here's the code (comment out all but one of the conditional variants):</p> <pre><code>#include &lt;iostream&gt; unsigned myrand() { static unsigned x = 1; return (x = x * 1664525 + 1013904223); } int main() { size_t count = 0; for(size_t i=0; i&lt;100000000; ++i ) { int a = 1 + myrand() % 26; int b = 1 + myrand() % 26; int c = 1 + myrand() % 26; count += 5 &amp; (((b-a) | (c-a)) &gt;&gt; 31); // 0.635 sec //if (((b-a) | (c-a)) &amp; 0x80) count += 5; // 0.660 sec //if (a &gt; std::max(b,c)) count += 5; // 0.677 sec //if ( a &gt; b || a &gt; c) count += 5; // 1.164 sec } std::cout &lt;&lt; count &lt;&lt; std::endl; return 0; } </code></pre> <p>The fastest is a modification on the suggestion in my answer, where we use sign extension to generate a mask that is either 32 <code>1s</code> or 32 <code>0s</code> depending on whether the condition is true of false, and use that to mask the <code>5</code> being added so that it either adds 5 or 0. This variation has no branches. The times are in a comment on each line. The slowest was the original expression <code>( a &gt; b || a &gt; c)</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

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