Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<pre><code>#include &lt;errno.h&gt; #include &lt;stdint.h&gt; /* Insert a bit `idx' positions from the right (lsb). */ uint16_t bit_insert_lsb(uint16_t n, int bit, int idx) { uint16_t lower; if (idx &gt; 15) { errno = ERANGE; return 0U; } /* Get bits 0 to `idx' inclusive. */ lower = n &amp; ((1U &lt;&lt; (idx + 1)) - 1); return ((n &amp; ~lower) | ((!!bit) &lt;&lt; idx) | (lower &gt;&gt; 1)); } /* Insert a bit `idx' positions from the left (msb). */ uint16_t bit_insert_msb(uint16_t n, int bit, int idx) { uint16_t lower; if (idx &gt; 15) { errno = ERANGE; return 0U; } /* Get bits 0 to `16 - idx' inclusive. */ lower = n &amp; ((1U &lt;&lt; (15 - idx + 1)) - 1); return ((n &amp; ~lower) | ((!!bit) &lt;&lt; (15 - idx)) | (lower &gt;&gt; 1)); } </code></pre> <p>Bits are typically counted from the right, where the least significant bit (lsb) resides, to the left, where the most significant bit (msb) is located. I allowed for insertion from either side by creating two functions. The one expected, according to the question, is <code>bit_insert_msb</code>.</p> <p>Both functions perform a sanity check, setting <code>errno</code> to <code>ERANGE</code> and returning 0 if the value of <code>idx</code> is too large. I also provided some of C99's <code>_Bool</code> behaviour for the <code>bit</code> parameter in the <code>return</code> statements: 0 is 0 and any other value is 1. If you use a C99 compiler, I'd recommend changing <code>bit</code>'s type to <code>_Bool</code>. You can then replace <code>(!!bit)</code> with <code>bit</code> directly.</p> <p>I'd love to say it could be optimised, but that could very well make it less comprehensible.</p> <p>Happy coding!</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