<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>C operator puzzles</title>
		<link>http://www.allegro.cc/forums/view/342372</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Tue, 16 Mar 2004 23:40:55 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Okay, my prof has set some really hard questions for my CS:APP-based computer systems class. I did half the problems fine but now I&#39;m completely stumped, and I consider myself a decent C programmer. You have to write functions that perform simple arithmetic or logical processes. The catch is that you are limited to using 8 different operators (or less): !, ~, &amp;, ^, |, +, &lt;&lt;, &gt;&gt;.  You cannot use any operators, any control structures or any macros. You cannot cast (implicitly or otherwise). You can use constants, but they must be between 0 and 255, inclusive. The number of operators you can use is limited, and the fewer the better.</p><p>You can use variables, though. And the assignment operator (=) doesn&#39;t count. And this all assumes 32 bit signed integers (meaning that right shifts are arithmetic, not logical).</p><p>Okay, I admit this is a &quot;do my homework&quot; topic, so I&#39;ll understand if this thread gets deleted. But as far as homework goes it&#39;s pretty on-topic for a C game programming site. Bit manipulation is necessary for low-level graphics programming, so hopefully we can all learn something from this <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />.</p><p>Here&#39;s an example to get you started. Create an isPositive(int x) function with a maximum of 8 operators. It must return 1 if x is positive, and 0 if x is negative or zero. Spoiler below.</p><p>...</p><p>...</p><p>...</p><p>Here&#39;s my answer in 6 ops:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> isPositive<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span>
    <span class="k1">int</span> y <span class="k3">=</span> <span class="k2">(</span>~<span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">31</span><span class="k2">)</span><span class="k2">)</span> <span class="k3">&amp;</span> <span class="n">1</span><span class="k2">;</span> <span class="c">// shift right to get sign bit, and then take complement and mask to LSB</span>
    <span class="k1">return</span> <span class="k2">(</span><span class="k3">!</span><span class="k3">!</span>x<span class="k2">)</span> <span class="k3">&amp;</span> y<span class="k2">;</span> <span class="c">// correctly handle special case x = 0</span>
<span class="k2">}</span>
</pre></div></div><p>

See if you can do better. Now, here are the hard ones that I&#39;ve been struggling with for hours with no results.</p><p>leastBitPos (int x) : return a mask that marks the position of the least significant 1 bit. If x == 0 return 0<br />Example: leastBitPos(96) = 0x20<br />Max ops: 6</p><p>logicalNeg (int x) : implement the ! operator, using all of the legal operators except !<br />Examples: logicalNeg(3) = 0, logicalNeg(0) = 1<br />Max ops: 12</p><p>isLess (int x, int y): if x &lt; y, then return 1, else return 0<br />Example: isLess(4, 5) = 1<br />Max Ops: 24</p><p>I can only hope my prof doesn&#39;t find this...But from looking at the mangled URLs, these forums probably aren&#39;t indexed by the googlebot.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (damage)</author>
		<pubDate>Mon, 15 Mar 2004 15:24:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>these forums probably aren&#39;t indexed by the googlebot</p></div></div><p>

Actually, they are. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Inphernic)</author>
		<pubDate>Mon, 15 Mar 2004 16:19:40 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>erm... if they are, you&#39;ve done something I can&#39;t. I con NOT get google to search through forums.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CGamesPlay)</author>
		<pubDate>Mon, 15 Mar 2004 18:26:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Cool <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /><br />Could you post all the questions, please?</p><p>And I do have a question... can I use the equality op (==)?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (spellcaster)</author>
		<pubDate>Mon, 15 Mar 2004 18:35:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>isLess (int x, int y): if x &lt; y, then return 1, else return 0<br />Example: isLess(4, 5) = 1<br />Max Ops: 24</p></div></div><p>
This one&#39;s actually pretty easy. The way most CPU&#39;s do it (from what I understand, anyways), is simply subtract the values, and check the sign bit.</p><p>4 operations:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> isLess<span class="k2">(</span><span class="k1">int</span> x, <span class="k1">int</span> y<span class="k2">)</span>
<span class="k2">{</span>
  <span class="k1">return</span> <span class="k2">(</span><span class="k3">!</span><span class="k2">(</span><span class="k2">(</span>y <span class="k3">+</span> ~x<span class="k2">)</span> <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">31</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
Uses two&#39;s-compliment to do subtraction with the addition operator, and right-shifts to check the sign bit.</p><p>Not really sure about the other two, though.</p><p>-Maverick
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Maverick)</author>
		<pubDate>Mon, 15 Mar 2004 18:46:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Actually I just checked google and Inphernic&#39;s quite right. But I shouldn&#39;t care anyway, I&#39;m just talking about the questions... it&#39;s free speech.</p><p>CGamesPlay - you can search the forums like <a href="http://www.google.com/search?hl=en&amp;lr=&amp;ie=UTF-8&amp;oe=UTF-8&amp;q=site%3Aallegro.cc+cgamesplay&amp;btnG=Google+Search">this</a> if you want. </p><p>Spellcaster: </p><p>Sorry, you can&#39;t use the equality operator or other comparison operators, just the following 8 operators: !, ~, &amp;, ^, |, +, &gt;&gt;, &lt;&lt;. Except for logicalNegate() in which you can&#39;t use !. (I just noticed I made a typo in the OP where I said you couldn&#39;t use &quot;any operators&quot;, but I meant &quot;any other operators&quot;.)</p><p>Here are the rest of questions, the ones that I could actually do. I&#39;ve done nearly all of them so I can post my own answers later if people are interested. But the good thing about these questions is that it&#39;s easy to check if you have the right answer or not - just compile and test your functions on some random values. And remember that you can only use constants between 0 and 255, and that = doesn&#39;t count towards your ops.</p><p>bitAnd(int x, int y): Return x &amp; y, but only using the ~ and | operators.<br />Max ops: 8</p><p>bitXor(int x, int y): Return x ^ y, but only using ~ and &amp; operators.<br />Max ops: 14 </p><p>evenBits(): Give 32 bit word with each even numbered bit set (.....010101).<br />Max ops: 8</p><p>getByte(int x, int n): From 32 bit word x, extract byte n, where LS byte is 0 and MS byte is 3.<br />Max ops: 6</p><p>bitMask (int high, int low): Return mask with bits from high to low set to one. E.g. bitMask(5, 2) should return ...00011100 in binary.<br />Max ops: 16</p><p>reverseBytes (int x): Return the bytes of x in reverse order, so that the MS byte is in LS place.<br />Max ops: 25</p><p>minusOne(): Return -1. Yes, that&#39;s all <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" />.<br />Max ops: 2</p><p>tmax(): Return maximum possible positive <b>signed</b> integer.<br />Max ops: 4</p><p>negate(int x): Return negative x<br />Max ops: 5</p><p>sm2tc(int x): Convert x from sign-mag form to 2&#39;s complement. Remember that sign-mag form uses the MSB to indicate sign but is otherwise the same as the unsigned format.<br />Max Ops: 15</p><p>Finally, this wasn&#39;t really a question but it&#39;s a pretty cool trick anyway that you may already know:</p><p>swap(int *x, int *y). Swap two integers. <br />Special: You can&#39;t use any extra variables, BUT you can use the dereference (*) operator which doesn&#39;t count towards your op total (like =).<br />Max Ops: 3</p><p>Maverick: Nice idea <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />, I actually tried that, but the problem is arithmetic overflow if x is a very low negative and y is a high positive. And by the way, to get -x, you need ~x + 1.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (damage)</author>
		<pubDate>Mon, 15 Mar 2004 19:11:04 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>I con NOT get google to search through forums.</p></div></div><p>

What a pity.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Inphernic)</author>
		<pubDate>Mon, 15 Mar 2004 19:13:27 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;ll give it a shot:
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="c">/* 4 ops (max 4) */</span></td></tr><tr><td class="number">2</td><td><span class="k1">int</span> bitAnd<span class="k2">(</span><span class="k1">int</span> x, <span class="k1">int</span> y<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">3</td><td>    <span class="k1">return</span> ~<span class="k2">(</span><span class="k2">(</span>~x<span class="k2">)</span> <span class="k3">|</span> <span class="k2">(</span>~y<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">4</td><td><span class="k2">}</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td><span class="c">/* 8 ops (max 14) */</span></td></tr><tr><td class="number">7</td><td><span class="k1">int</span> bitXor<span class="k2">(</span><span class="k1">int</span> x, <span class="k1">int</span> y<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">8</td><td>    <span class="k1">return</span> ~<span class="k2">(</span><span class="k2">(</span>~<span class="k2">(</span>x <span class="k3">&amp;</span> <span class="k2">(</span>~y<span class="k2">)</span><span class="k2">)</span><span class="k2">)</span> <span class="k3">&amp;</span> <span class="k2">(</span>~<span class="k2">(</span><span class="k2">(</span>~x<span class="k2">)</span> <span class="k3">&amp;</span> y<span class="k2">)</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">9</td><td><span class="k2">}</span></td></tr><tr><td class="number">10</td><td>&#160;</td></tr><tr><td class="number">11</td><td><span class="c">/* 4 ops (max 8) */</span></td></tr><tr><td class="number">12</td><td><span class="k1">int</span> evenBits<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">13</td><td>    <span class="k1">int</span> y <span class="k3">=</span> <span class="n">85</span><span class="k2">;</span></td></tr><tr><td class="number">14</td><td>    y <span class="k3">|</span><span class="k3">=</span> y <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">8</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>    y <span class="k3">|</span><span class="k3">=</span> y <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">16</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>    <span class="k1">return</span> y<span class="k2">;</span></td></tr><tr><td class="number">17</td><td><span class="k2">}</span></td></tr><tr><td class="number">18</td><td>&#160;</td></tr><tr><td class="number">19</td><td>&#160;</td></tr><tr><td class="number">20</td><td><span class="c">/* 3 ops (max 6) */</span></td></tr><tr><td class="number">21</td><td><span class="k1">int</span> getByte<span class="k2">(</span><span class="k1">int</span> x, <span class="k1">int</span> n<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">22</td><td>    <span class="k1">int</span> shift <span class="k3">=</span> n <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">3</span><span class="k2">;</span></td></tr><tr><td class="number">23</td><td>    <span class="k1">return</span> <span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> shift<span class="k2">)</span> <span class="k3">&amp;</span> <span class="n">255</span><span class="k2">;</span></td></tr><tr><td class="number">24</td><td><span class="k2">}</span></td></tr><tr><td class="number">25</td><td>&#160;</td></tr><tr><td class="number">26</td><td><span class="c">/* 5 ops (max 16) */</span></td></tr><tr><td class="number">27</td><td><span class="k1">int</span> bitMask<span class="k2">(</span><span class="k1">int</span> a, <span class="k1">int</span> b<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">28</td><td>    <span class="k1">return</span> <span class="k2">(</span><span class="k2">(</span><span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> a<span class="k2">)</span> <span class="k3">-</span> <span class="n">1</span><span class="k2">)</span> ^ <span class="k2">(</span><span class="k2">(</span><span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> b<span class="k2">)</span> <span class="k3">-</span> <span class="n">1</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">29</td><td><span class="k2">}</span></td></tr><tr><td class="number">30</td><td>&#160;</td></tr><tr><td class="number">31</td><td>&#160;</td></tr><tr><td class="number">32</td><td><span class="c">/* 1 op (max 2) */</span></td></tr><tr><td class="number">33</td><td><span class="k1">int</span> minusOne<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">34</td><td>    <span class="k1">return</span> ~<span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">35</td><td><span class="k2">}</span></td></tr><tr><td class="number">36</td><td>&#160;</td></tr><tr><td class="number">37</td><td>&#160;</td></tr><tr><td class="number">38</td><td><span class="c">/* 2 ops (max 4) */</span></td></tr><tr><td class="number">39</td><td><span class="k1">int</span> tmax<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">40</td><td>    <span class="k1">return</span> <span class="k2">(</span><span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">31</span><span class="k2">)</span> <span class="k3">-</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">41</td><td><span class="k2">}</span></td></tr><tr><td class="number">42</td><td>&#160;</td></tr><tr><td class="number">43</td><td>&#160;</td></tr><tr><td class="number">44</td><td><span class="c">/* 2 ops (max 5) */</span></td></tr><tr><td class="number">45</td><td><span class="k1">int</span> negate<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">46</td><td>    <span class="k1">return</span> <span class="k2">(</span>~x<span class="k2">)</span> <span class="k3">+</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">47</td><td><span class="k2">}</span></td></tr><tr><td class="number">48</td><td>    </td></tr><tr><td class="number">49</td><td>&#160;</td></tr><tr><td class="number">50</td><td><span class="c">/* 14 ops (max 15) */</span></td></tr><tr><td class="number">51</td><td><span class="k1">int</span> sm2tc<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">52</td><td>    <span class="k1">int</span> sign <span class="k3">=</span> <span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">31</span><span class="k2">)</span> <span class="k3">&amp;</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">53</td><td>    sign <span class="k3">|</span><span class="k3">=</span> sign <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">54</td><td>    sign <span class="k3">|</span><span class="k3">=</span> sign <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">55</td><td>    sign <span class="k3">|</span><span class="k3">=</span> sign <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">4</span><span class="k2">;</span></td></tr><tr><td class="number">56</td><td>    sign <span class="k3">|</span><span class="k3">=</span> sign <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">8</span><span class="k2">;</span></td></tr><tr><td class="number">57</td><td>    sign <span class="k3">|</span><span class="k3">=</span> sign <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">16</span><span class="k2">;</span></td></tr><tr><td class="number">58</td><td>    <span class="k1">return</span> <span class="k2">(</span>x ^ sign<span class="k2">)</span> <span class="k3">-</span> sign<span class="k2">;</span></td></tr><tr><td class="number">59</td><td><span class="k2">}</span></td></tr><tr><td class="number">60</td><td>&#160;</td></tr><tr><td class="number">61</td><td>&#160;</td></tr><tr><td class="number">62</td><td><span class="c">/* 3 ops (max 3) */</span></td></tr><tr><td class="number">63</td><td><span class="c">/* IMPORTANT NOTE - if a == b, this will not work. */</span></td></tr><tr><td class="number">64</td><td><span class="k1">void</span> swap<span class="k2">(</span><span class="k1">int</span> <span class="k3">*</span>a, <span class="k1">int</span> <span class="k3">*</span>b<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">65</td><td>    <span class="k2">(</span><span class="k3">*</span>a<span class="k2">)</span> ^<span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>b<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">66</td><td>    <span class="k2">(</span><span class="k3">*</span>b<span class="k2">)</span> ^<span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>a<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">67</td><td>    <span class="k2">(</span><span class="k3">*</span>a<span class="k2">)</span> ^<span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>b<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">68</td><td><span class="k2">}</span></td></tr><tr><td class="number">69</td><td>&#160;</td></tr><tr><td class="number">70</td><td>&#160;</td></tr><tr><td class="number">71</td><td><span class="c">/* 2ops (max 6) */</span></td></tr><tr><td class="number">72</td><td><span class="k1">int</span> leastBitPos<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">73</td><td>    <span class="k1">return</span> x <span class="k3">&amp;</span> <span class="k2">(</span><span class="k3">-</span>x<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">74</td><td><span class="k2">}</span></td></tr><tr><td class="number">75</td><td>&#160;</td></tr><tr><td class="number">76</td><td>&#160;</td></tr><tr><td class="number">77</td><td><span class="c">/* 12 ops (max 12) */</span></td></tr><tr><td class="number">78</td><td><span class="k1">int</span> logicalNeg<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">79</td><td>     x <span class="k3">|</span><span class="k3">=</span> x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">80</td><td>     x <span class="k3">|</span><span class="k3">=</span> x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">81</td><td>     x <span class="k3">|</span><span class="k3">=</span> x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">4</span><span class="k2">;</span></td></tr><tr><td class="number">82</td><td>     x <span class="k3">|</span><span class="k3">=</span> x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">8</span><span class="k2">;</span></td></tr><tr><td class="number">83</td><td>     x <span class="k3">|</span><span class="k3">=</span> x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">16</span><span class="k2">;</span></td></tr><tr><td class="number">84</td><td>     <span class="k1">return</span> ~x <span class="k3">&amp;</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">85</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>


Edit: Some useful links:<br /><a href="http://aggregate.org/MAGIC/">Aggregate Magic</a><br /><a href="http://bob.allegronetwork.com/prog/tricks.html">My own webpage</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bob)</author>
		<pubDate>Mon, 15 Mar 2004 21:36:24 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>/* 2 ops (max 4) */<br />int tmax() {<br />    return (1 &lt;&lt; 31) - 1;<br />}
</p></div></div><p>
-<br />is not an allowed op. So you have to use the 2&#39;s complement.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (spellcaster)</author>
		<pubDate>Mon, 15 Mar 2004 23:23:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>/* 3 ops (max 3) */<br />/* IMPORTANT NOTE - if a == b, this will not work. */<br />void swap(int *a, int *b) {<br />    (*a) ^= (*b);<br />    (*b) ^= (*a);<br />    (*a) ^= (*b);<br />}</p></div></div><p>
</p><pre>  a  b
 15 15    a^=b
  0 15    b^=a
  0 15    a^=b
 15 15</pre><p>
It still works. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>Actually, if this didn`t work for a==b it wouldn`t work for any a and b which have at least one equal bit, so it would work only when a == ~b.</p><p>Edit: *a^=*b^=*a^=*b; looks imho better <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Krzysztof Kluczek)</author>
		<pubDate>Tue, 16 Mar 2004 00:00:41 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>Actually, if this didn`t work for a==b it wouldn`t</p></div></div><p>
It still doesn&#39;t work for a == b. Try it out <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /><br />It does work if *a == *b, however <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /></p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>- is not an allowed op.</p></div></div><p>
D&#39;oh. Well, let&#39;s try this again then:</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="c">/* 7 ops (max 16) */</span></td></tr><tr><td class="number">2</td><td><span class="k1">int</span> bitMask<span class="k2">(</span><span class="k1">int</span> a, <span class="k1">int</span> b<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">3</td><td>    <span class="k1">return</span> <span class="k2">(</span><span class="k2">(</span><span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> a<span class="k2">)</span> <span class="k3">+</span> ~<span class="n">0</span><span class="k2">)</span> ^ <span class="k2">(</span><span class="k2">(</span><span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> b<span class="k2">)</span> <span class="k3">+</span> ~<span class="n">0</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">4</td><td><span class="k2">}</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td><span class="c">/* 3 ops (max 4) */</span></td></tr><tr><td class="number">7</td><td><span class="k1">int</span> tmax<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">8</td><td>    <span class="k1">return</span> <span class="k2">(</span><span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">31</span><span class="k2">)</span> <span class="k3">+</span> ~<span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">9</td><td><span class="k2">}</span></td></tr><tr><td class="number">10</td><td>&#160;</td></tr><tr><td class="number">11</td><td><span class="c">/* 14 ops (max 15) */</span></td></tr><tr><td class="number">12</td><td><span class="k1">int</span> sm2tc<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">13</td><td>    <span class="k1">int</span> sign <span class="k3">=</span> <span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">31</span><span class="k2">)</span> <span class="k3">&amp;</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">14</td><td>    <span class="k1">int</span> mask <span class="k3">=</span> sign <span class="k3">|</span> <span class="k2">(</span>sign <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">1</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>    mask <span class="k3">|</span><span class="k3">=</span> mask <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>    mask <span class="k3">|</span><span class="k3">=</span> mask <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">4</span><span class="k2">;</span></td></tr><tr><td class="number">17</td><td>    mask <span class="k3">|</span><span class="k3">=</span> mask <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">8</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td>    mask <span class="k3">|</span><span class="k3">=</span> mask <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">15</span><span class="k2">;</span></td></tr><tr><td class="number">19</td><td>    <span class="k1">return</span> <span class="k2">(</span>x ^ mask<span class="k2">)</span> <span class="k3">+</span> sign<span class="k2">;</span></td></tr><tr><td class="number">20</td><td><span class="k2">}</span></td></tr><tr><td class="number">21</td><td>&#160;</td></tr><tr><td class="number">22</td><td>&#160;</td></tr><tr><td class="number">23</td><td><span class="c">/* 3ops (max 6) */</span></td></tr><tr><td class="number">24</td><td><span class="k1">int</span> leastBitPos<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">25</td><td>    <span class="k1">return</span> x <span class="k3">&amp;</span> <span class="k2">(</span><span class="k2">(</span>~x<span class="k2">)</span> <span class="k3">+</span> <span class="n">1</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">26</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

Edit: Fixed typos in sm2tc().
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bob)</author>
		<pubDate>Tue, 16 Mar 2004 00:06:07 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>It still doesn&#39;t work for a == b.</p></div></div><p>
Well, I misinterpreted it then. I thought a and b meant pointed variables. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Krzysztof Kluczek)</author>
		<pubDate>Tue, 16 Mar 2004 00:24:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">CGP said:</div><div class="quote"><p>
erm... if they are, you&#39;ve done something I can&#39;t. I con NOT get google to search through forums. 
</p></div></div><p>

try <a href="http://www.google.com/search?sourceid=navclient&amp;q=site:www%2Eallegro%2Ecc+question">http://www.google.com/search?sourceid=navclient&amp;q=site:www%2Eallegro%2Ecc+question</a></p><p><img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (BAF)</author>
		<pubDate>Tue, 16 Mar 2004 02:36:35 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Wow, Bob, that&#39;s some good answers. I think you&#39;d ace my course. Just looking over them quickly:</p><p>The first two are definitely right as you got the same as me. They are pretty straightforward applications of boolean algebra.</p><p>For EvenBits you&#39;ve managed to use about half the number of ops I used, by unwrapping it piece-by-piece. That&#39;s a neat trick.</p><p>Getbyte is the same, but that&#39;s a pretty simple one.</p><p>Your bitmask is a LOT less complicated and uses 4 less ops than mine. I understand what you&#39;re doing, and that&#39;s a really good idea. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>Your tmax, minusone and negate are basically the same as mine, so they&#39;re right.</p><p>I don&#39;t know about logicalneg and leastbitpos, as I haven&#39;t done them myself, but I&#39;ll run the automated tests on your answers at Uni today and tell you how many you got right. From first glance I think you&#39;ve probably got all of them right. </p><p>The main thing I missed seems to be the whole &quot;wrapping&quot; trick of performing &gt;&gt; 16 followed by &gt;&gt; 8, &gt;&gt; 4, &gt;&gt; 2 and &gt;&gt; 1 and doing it the other way.</p><p>And the swap function is right, too. Good point about the fact that it doesn&#39;t work when x == y, I should have added that in the question.</p><p><img src="http://www.allegro.cc/forums/smileys/cool.gif" alt="8-)" /></p><p>EDIT: Those are some really good links by the way.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (damage)</author>
		<pubDate>Tue, 16 Mar 2004 04:24:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">damage said:</div><div class="quote"><p>Maverick: Nice idea , I actually tried that, but the problem is arithmetic overflow if x is a very low negative and y is a high positive. And by the way, to get -x, you need ~x + 1. </p></div></div><p>
Yeah, but there really isn&#39;t much you can do about the overflow besides splitting each argument into 16-bits and doing each set in its own 32-bit var.<br />About -x = ~x + 1... Yeah, but it doesn&#39;t matter in this case, since y - x - 1 (or, y + ~x) gives the range -inf to -1 if x is bigger or they&#39;re equal (sign bit set), and 0 to inf if x is smaller (sign bit unset).</p><p>-Maverick
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Maverick)</author>
		<pubDate>Tue, 16 Mar 2004 05:29:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>Yeah, but there really isn&#39;t much you can do about the overflow besides splitting each argument into 16-bits and doing each set in its own 32-bit var.</p></div></div><p>
Since you are limited to 24 ops in this one I think actually you can do it. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Krzysztof Kluczek)</author>
		<pubDate>Tue, 16 Mar 2004 05:56:28 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ok, just tried Bob&#39;s answers with the rigorous automated tester. All of them worked, but here&#39;s a few things:</p><p>You had the order around the wrong way with logicalNeg, but apart from that it was fine.</p><p>leastBitPos worked perfectly.</p><p>Your smtc() didn&#39;t quite work (because you forgot to remove the sign bit), but it inspired me to write a shorter version, taking advantage of arithmetic shifting:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> sm2tc<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span>
  <span class="k1">int</span> sign <span class="k3">=</span> <span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">31</span><span class="k2">)</span><span class="k2">;</span>
  x <span class="k3">=</span> x <span class="k3">+</span> <span class="k2">(</span>sign <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">31</span><span class="k2">)</span><span class="k2">;</span> <span class="c">// remove sign bit</span>
  <span class="k1">return</span> <span class="k2">(</span>x ^ sign<span class="k2">)</span> <span class="k3">+</span> <span class="k2">(</span>sign <span class="k3">&amp;</span> <span class="n">1</span><span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

Your bitmask required one small adjustment (an extra +1) to account for the fact that the range is inclusive, but that&#39;s probably because I didn&#39;t specify the problem well enough.</p><p>Thanks again for the help. I actually feel like I understand all the problems now, so it&#39;s a big relief.</p><p>Maverick: Yeah, I should have seen realized that it was intentional, sorry. </p><p>Good idea about splitting it up, I think I will try that, and compare each 16-bit segment separately and then combine the results using bitwise operators.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (damage)</author>
		<pubDate>Tue, 16 Mar 2004 11:28:00 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>Your smtc() didn&#39;t quite work (because you forgot to remove the sign bit)</p></div></div><p>
On the contrary - I removed the sign bit completely. I forgot to put it back! In any case, it should be fixed now.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p> taking advantage of arithmetic shifting:</p></div></div><p>
True, but in C, right-shifts are undefined with respect to arithmetic vs logical, so I didn&#39;t want to impose one more assumption.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>Your bitmask required one small adjustment (an extra +1) to account for the fact that the range is inclusive</p></div></div><p>
Inclusive range?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bob)</author>
		<pubDate>Tue, 16 Mar 2004 11:56:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Bob, you&#39;re very right about the arithmetic shifting, but fortunately the question sheet explicitly states that we can assume arithmetic shifting. Sorry, I think I forgot to say that in the OP.</p><p>What I meant by &quot;inclusive range&quot; is that if you, say, call bitmask(5, 3) then it should produce 0x38, which in binary is:
</p><div class="source-code snippet"><div class="inner"><pre>value  ...<span class="n">000111000</span>
bit    ...<span class="n">876543210</span>
</pre></div></div><p>
So bits from 5 to 3 inclusively are set.</p><p>If anyone&#39;s interested, here&#39;s a working version of isLess() I just hacked up, but it probably doesn&#39;t have an optimal number of ops (18!), and it may have some unnecessary logic:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> y_minus_x<span class="k2">;</span>
<span class="k1">int</span> z <span class="k3">=</span> x <span class="k3">&amp;</span> <span class="n">1</span><span class="k2">;</span>
<span class="k1">int</span> w <span class="k3">=</span> y <span class="k3">&amp;</span> <span class="n">1</span><span class="k2">;</span>

x <span class="k3">=</span> x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">1</span><span class="k2">;</span>
y <span class="k3">=</span> y <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">1</span><span class="k2">;</span>

y_minus_x <span class="k3">=</span> <span class="k2">(</span>y <span class="k3">+</span> <span class="k2">(</span>~x<span class="k2">)</span> <span class="k3">+</span> <span class="n">1</span><span class="k2">)</span><span class="k2">;</span>

<span class="k1">return</span> <span class="k2">(</span><span class="k3">!</span><span class="k3">!</span>y_minus_x<span class="k2">)</span> <span class="k3">&amp;</span> <span class="k2">(</span><span class="k3">!</span><span class="k2">(</span><span class="k2">(</span>y_minus_x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">31</span><span class="k2">)</span> <span class="k3">&amp;</span> <span class="n">1</span><span class="k2">)</span> <span class="k3">|</span> <span class="k2">(</span><span class="k2">(</span><span class="k3">!</span>y_minus_x<span class="k2">)</span> <span class="k3">&amp;</span> z <span class="k3">&amp;</span> <span class="k3">!</span>w<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
So now I&#39;ve finished the lot, but if anyone can reduce the number of ops used, I&#39;m interested!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (damage)</author>
		<pubDate>Tue, 16 Mar 2004 13:02:19 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p> but fortunately the question sheet explicitly states that we can assume arithmetic shifting.</p></div></div><p>
Well, that changes a lot of things! I can reduce the code size of sm2tc some more:</p><div class="source-code snippet"><div class="inner"><pre><span class="c">/* 7 ops (max 15) */</span>
<span class="k1">int</span> sm2tc<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span>
    <span class="k1">int</span> sign <span class="k3">=</span> <span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">31</span><span class="k2">)</span> <span class="k3">&amp;</span> <span class="n">1</span><span class="k2">;</span>
    <span class="k1">int</span> mask <span class="k3">=</span> <span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">31</span><span class="k2">)</span> ^ <span class="k2">(</span><span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">31</span><span class="k2">)</span><span class="k2">;</span>
    <span class="k1">return</span> <span class="k2">(</span>x ^ mask<span class="k2">)</span> <span class="k3">+</span> sign<span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

I also forgot about this one:
</p><div class="source-code snippet"><div class="inner"><pre><span class="c">/* 12 ops (max 25) */</span>
<span class="k1">int</span> reverseBytes<span class="k2">(</span><span class="k1">int</span> x<span class="k2">)</span> <span class="k2">{</span>
    <span class="k1">int</span> a <span class="k3">=</span> <span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">8</span><span class="k2">)</span> <span class="k3">&amp;</span> <span class="n">255</span><span class="k2">;</span>
    <span class="k1">int</span> b <span class="k3">=</span> <span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">16</span><span class="k2">)</span> <span class="k3">&amp;</span> <span class="n">255</span><span class="k2">;</span>
    <span class="k1">int</span> c <span class="k3">=</span> <span class="k2">(</span>x <span class="k3">&gt;</span><span class="k3">&gt;</span> <span class="n">24</span><span class="k2">)</span> <span class="k3">&amp;</span> <span class="n">255</span><span class="k2">;</span>
    <span class="k1">return</span> <span class="k2">(</span>x <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">24</span><span class="k2">)</span> <span class="k3">|</span> <span class="k2">(</span>a <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">16</span><span class="k2">)</span> <span class="k3">|</span> <span class="k2">(</span>b <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">8</span><span class="k2">)</span> <span class="k3">|</span> c<span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bob)</author>
		<pubDate>Tue, 16 Mar 2004 13:34:18 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>True, but in C, right-shifts are undefined with respect to arithmetic vs logical, so I didn&#39;t want to impose one more assumption.</p></div></div><p>
I thought they are meant to be arithmetic when working on signed values and logical with unsigned ones.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Krzysztof Kluczek)</author>
		<pubDate>Tue, 16 Mar 2004 21:26:47 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Me too.</p><p>With unsigned, arithmetic shift == logic shift always.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Oscar Giner)</author>
		<pubDate>Tue, 16 Mar 2004 23:24:58 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">The Standard said:</div><div class="quote"><p>
The result of E1 &gt;&gt; E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type<br />or if E1 has a signed type and a nonnegative value, the value of the result is the integral<br />part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the<br />resulting value is implementation-defined.
</p></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bob)</author>
		<pubDate>Tue, 16 Mar 2004 23:40:55 +0000</pubDate>
	</item>
</rss>
