user4603: I'm trying to store a state in my data logger. I can read/write fine to SD, but I can't wrap my head around reading/writing a long value correctly - I've build it down to converting it to char array and back.
My best try so far has been 
long temp = 1418172669L;
unsigned char buf[4];
buf[0] = temp         & 0xFF;
buf[1] = (temp >>  8) & 0xFF;
buf[2] = (temp >> 16) & 0xFF;
buf[3] = (temp >> 24) & 0xFF;

long  l = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);

But l is very different from temp - currently the output is -26371. Am I making an obvious mistake?

user84: I think the last expression is performed exclusively as an int expression and converted to long only at the end, i.e. before assignment to l. 
long  l = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);

Here the compiler calculates buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24) as an int only.
If you give a hint to the compiler by telling it you want long expressions used, then it should work. The easiest way to do so is to replace the number of bits to be shifted as long literals:
long  l = buf[0] | (buf[1] << 8L) | (buf[2] << 16L) | (buf[3] << 24L);

That should be enough for the compiler to perform the whole operation as long and not loose precision.

user2778: I suggest using a union:
union {
    char myByte[4];
    long mylong;
} foo;

Char to Long:
Then you can just add the bytes:
foo myUnion;
myUnion.myByte[0] = buf[0];
myUnion.myByte[1] = buf[1];
myUnion.myByte[2] = buf[2];
myUnion.myByte[3] = buf[3];

Then you can access the long as:
myUnion.myLong;

Long to Char:
The same if you want to go the other way from long to char array:
foo myUnion
myUnion.myLong = 1234L;

To access bytes:
myUnion.myByte[0];
myUnion.myByte[1];
myUnion.myByte[2];
myUnion.myByte[3];


4603: <p>I'm trying to store a state in my data logger. I can read/write fine to SD, but I can't wrap my head around reading/writing a <code>long</code> value correctly - I've build it down to converting it to char array and back.</p>

<p>My best try so far has been </p>

<pre><code>long temp = 1418172669L;
unsigned char buf[4];
buf[0] = temp         &amp; 0xFF;
buf[1] = (temp &gt;&gt;  8) &amp; 0xFF;
buf[2] = (temp &gt;&gt; 16) &amp; 0xFF;
buf[3] = (temp &gt;&gt; 24) &amp; 0xFF;

long  l = buf[0] | (buf[1] &lt;&lt; 8) | (buf[2] &lt;&lt; 16) | (buf[3] &lt;&lt; 24);
</code></pre>

<p>But <code>l</code> is very different from <code>temp</code> - currently the output is <code>-26371</code>. Am I making an obvious mistake?</p>
 84: <p>I think the last expression is performed exclusively as an <code>int</code> expression and converted to <code>long</code> only at the end, i.e. before assignment to <code>l</code>. </p>

<pre><code>long  l = buf[0] | (buf[1] &lt;&lt; 8) | (buf[2] &lt;&lt; 16) | (buf[3] &lt;&lt; 24);
</code></pre>

<p>Here the compiler calculates <code>buf[0] | (buf[1] &lt;&lt; 8) | (buf[2] &lt;&lt; 16) | (buf[3] &lt;&lt; 24)</code> as an <code>int</code> only.</p>

<p>If you give a hint to the compiler by telling it you want <code>long</code> expressions used, then it should work. The easiest way to do so is to replace the number of bits to be shifted as <strong>long literals</strong>:</p>

<pre><code>long  l = buf[0] | (buf[1] &lt;&lt; 8L) | (buf[2] &lt;&lt; 16L) | (buf[3] &lt;&lt; 24L);
</code></pre>

<p>That should be enough for the compiler to perform the whole operation as <code>long</code> and not loose precision.</p>
 2778: <p>I suggest using a union:</p>

<pre><code>union {
    char myByte[4];
    long mylong;
} foo;
</code></pre>

<p><strong>Char to Long:</strong></p>

<p>Then you can just add the bytes:</p>

<pre><code>foo myUnion;
myUnion.myByte[0] = buf[0];
myUnion.myByte[1] = buf[1];
myUnion.myByte[2] = buf[2];
myUnion.myByte[3] = buf[3];
</code></pre>

<p>Then you can access the long as:</p>

<pre><code>myUnion.myLong;
</code></pre>

<p><strong>Long to Char:</strong></p>

<p>The same if you want to go the other way from long to char array:</p>

<pre><code>foo myUnion
myUnion.myLong = 1234L;
</code></pre>

<p>To access bytes:</p>

<pre><code>myUnion.myByte[0];
myUnion.myByte[1];
myUnion.myByte[2];
myUnion.myByte[3];
</code></pre>
