title: Conversion of long long to byte array and back in c++
body: <p>I've written a test to try and figure out how conversion between <code>char[]</code> arrays and <code>long long</code> can work. Partially for my own understanding, I'm trying to figure out the bitwise method of doing so.</p>
  
  <p>Conceptually, for a <code>long long</code> to a <code>char[]</code>, the below feels right.  I'm shifting left, then AND-ing to limit to the right:</p>
  
  <pre><code>for (int i = 0; i &lt; BUFFER_SIZE; i++)
  {
      buffer[i] = ((value &gt;&gt; (8 * i)) &amp; 0XFF);
  }
  </code></pre>
  
  <p>To convert back, shift left and sum over the buffer:</p>
  
  <pre><code>long long recoveredValue = 0;
  for (int i = 0; i &lt; BUFFER_SIZE; i++)
  {
      auto byteVal = ((buffer[i]) &lt;&lt; (8 * i));
      recoveredValue = recoveredValue + byteVal;
  }
  </code></pre>
  
  <p>Below is my whole test program.  It seems as though when I'm filling the doing the first step above (in <code>IntToByteArray</code>) the value of <code>buffer[0]</code> is repeated at `buffer[32]'.   I know there's a problem here, but I can't figure it out.  </p>
  
  <p>Note that for my application, I have a <code>BUFFER_SIZE</code> of 63, and my <code>long long</code> will be limited to below 2^63.  Also, if I restrict <code>BUFFER_SIZE</code> to below 32, it works.  I'm missing a subtlty regarding the 64 bit int aren't I?  But where, &amp; how?</p>
  
  <pre><code>// Test_BitConversion.cpp : Defines the entry point for the console application.
  //
  
  #include "stdafx.h"
  #include &lt;cmath&gt;
  
  
  #define BUFFER_SIZE 64
  unsigned char buffer[BUFFER_SIZE] = { 0 };  // This is the buffer I have available
  
  // useful alternative method for checking conversion 
  // can't use in production, because I'm moving between C++ &amp; C#
  union byteunion 
  {
      long long value;
      unsigned char arr[BUFFER_SIZE];
  };
  
  
  // Convert long long to byte array
  void IntToByteArray(long long value)
  {
      for (int i = 0; i &lt; BUFFER_SIZE; i++)
      {
          buffer[i] = ((value &gt;&gt; (8 * i)) &amp; 0XFF);
      }
  }
  
  // Convert byte array to long long
  long long ByteArrayToInt()
  {
      long long recoveredValue = 0;
      for (int i = 0; i &lt; BUFFER_SIZE; i++)
      {
          auto byteVal = ((buffer[i]) &lt;&lt; (8 * i));
          recoveredValue = recoveredValue + byteVal;
      }
      return recoveredValue;
  }
  
  // Test union can convert value both directions
  bool TestUnion(long long value)
  {
      byteunion originalUnion, recoveredUnion;
      originalUnion.value = value;
  
  
      for (int a = 0; a &lt; BUFFER_SIZE; a++)
      {
          recoveredUnion.arr[a] = originalUnion.arr[a];
      }
  
      if (recoveredUnion.value != value)
      {
          printf("Union value failed");
          return false;
      }
  
      return true;
  }
  
  
  int main()
  {
  
      long long originalValue = 2004293008363;
      originalValue = (long long)std::pow(2, 31);
      long long recoveredValue = 0;
      byteunion originalUnion;
      originalUnion.value = originalValue;
  
  
      // Loop to find failure point
      for (int i = 1; i &lt; BUFFER_SIZE; i++)
      {
          originalValue = (long long)std::pow(2, i);
  
          // First check Union method
          bool unionTest = TestUnion(originalValue);
          if (!unionTest)
          {
              printf("Fail on Union at 2^%i", i);
              break; // this is never reached - union method works
          }
  
  
          // convert value to byte array
          IntToByteArray(originalValue);
  
          // now convert buffer back to long long
          recoveredValue = ByteArrayToInt();
  
  
          if (originalValue != recoveredValue)
          {
              printf("Fail recoving at 2^%i\n", i);
              break;  // this is reached when the original value is 2^31
          }
  
      }
  
      printf(" OriginalValue: %llu\n", originalValue);
      printf("RecoveredValue: %llu\n", recoveredValue);
  
      system("pause");
  
      return 0;
  }
  </code></pre>