user8687: I were examining shiftOut() function code in wiring_shift.c and I didn't quite understand what is going in digitalWrite function. I see !!(val & (1 << i)) is taking the bit value from val but how exactly it works?
The whole function is below.
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        if (bitOrder == LSBFIRST)
            digitalWrite(dataPin, !!(val & (1 << i)));
        else    
            digitalWrite(dataPin, !!(val & (1 << (7 - i))));

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);        
    }
}


user7508: I'll assume bitOrder == LSBFIRST.

i is the bit number, i.e. the “index” of the next bit to write
1 is 00000001 in binary
<< is the shift left operator. It returns its first argument shifted left by as many positions as indicated by the second argument
1<<i is binary 00000001 shifted left by i positions, i.e. something like 0...010...0, where the single 1 is in the i-th position counting from the right (rightmost being position 0)
& is the “bitwise and operator”, where any_bit & 0 is zero and any_bit & 1 is any_bit
val & (1 << i) is 0...0(i-th bit of val)0...0 in binary, where the i-th bit of val is in the i-th position of the result
!! is a double negation: it converts zero to zero and any non-zero value to one
!!(val & (1 << i)) is either 0 or 1, and is exactly the i-th bit of val


8687: <p>I were examining <code>shiftOut()</code> function code in <code>wiring_shift.c</code> and I didn't quite understand what is going in digitalWrite function. I see <code>!!(val &amp; (1 &lt;&lt; i))</code> is taking the bit value from <code>val</code> but how exactly it works?</p>

<p>The whole function is below.</p>

<pre><code>void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
    uint8_t i;

    for (i = 0; i &lt; 8; i++)  {
        if (bitOrder == LSBFIRST)
            digitalWrite(dataPin, !!(val &amp; (1 &lt;&lt; i)));
        else    
            digitalWrite(dataPin, !!(val &amp; (1 &lt;&lt; (7 - i))));

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);        
    }
}
</code></pre>
 7508: <p>I'll assume <code>bitOrder == LSBFIRST</code>.</p>

<ul>
<li><code>i</code> is the bit number, i.e. the “index” of the next bit to write</li>
<li><code>1</code> is <code>00000001</code> in binary</li>
<li><code>&lt;&lt;</code> is the shift left operator. It returns its first argument shifted left by as many positions as indicated by the second argument</li>
<li><code>1&lt;&lt;i</code> is binary <code>00000001</code> shifted left by <code>i</code> positions, i.e. something like <code>0...010...0</code>, where the single 1 is in the i-th position counting from the right (rightmost being position 0)</li>
<li><code>&amp;</code> is the “bitwise and operator”, where <code>any_bit &amp; 0</code> is zero and <code>any_bit &amp; 1</code> is <code>any_bit</code></li>
<li><code>val &amp; (1 &lt;&lt; i)</code> is <code>0...0(i-th bit of val)0...0</code> in binary, where the i-th bit of val is in the i-th position of the result</li>
<li><code>!!</code> is a double negation: it converts zero to zero and any non-zero value to one</li>
<li><code>!!(val &amp; (1 &lt;&lt; i))</code> is either 0 or 1, and is exactly the i-th bit of val</li>
</ul>
