Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><a href="http://msdn.microsoft.com/en-us/library/system.io.binaryreader.readint64.aspx" rel="noreferrer"><code>BinaryReader.ReadInt64</code></a> is little endian by design. From the documentation:</p> <blockquote> <p>BinaryReader reads this data type in little-endian format.</p> </blockquote> <p>In fact, we can inspect the source for <code>BinaryReader.ReadInt64</code> using Reflector.</p> <pre><code>public virtual long ReadInt64() { this.FillBuffer(8); uint num = (uint) (((this.m_buffer[0] | (this.m_buffer[1] &lt;&lt; 0x08)) | (this.m_buffer[2] &lt;&lt; 0x10)) | (this.m_buffer[3] &lt;&lt; 0x18)); uint num2 = (uint) (((this.m_buffer[4] | (this.m_buffer[5] &lt;&lt; 0x08)) | (this.m_buffer[6] &lt;&lt; 0x10)) | (this.m_buffer[7] &lt;&lt; 0x18)); return (long) ((num2 &lt;&lt; 0x20) | num); } </code></pre> <p>Showing that <code>BinaryReader.ReadInt64</code> reads as little endian independent of the underlying machine architecture.</p> <p>Now, <a href="http://msdn.microsoft.com/en-us/library/system.bitconverter.toint64.aspx" rel="noreferrer"><code>BitConverter.ToInt64</code></a> is suppose to respect the endianness of your underlying machine. In Reflector we can see</p> <pre><code>public static unsafe long ToInt64(byte[] value, int startIndex) { // argument checking elided fixed (byte* numRef = &amp;(value[startIndex])) { if ((startIndex % 8) == 0) { return *(((long*) numRef)); } if (IsLittleEndian) { int num = (numRef[0] &lt;&lt; 0x00) | (numRef[1] &lt;&lt; 0x08) | (numRef[2] &lt;&lt; 0x10) | (numRef[3] &lt;&lt; 0x18); int num2 = (numRef[4] &lt;&lt; 0x00) | (numRef[5] &lt;&lt; 0x08) | (numRef[6] &lt;&lt; 0x10) | (numRef[7] &lt;&lt; 0x18); return (((long) ((ulong) num)) | (num2 &lt;&lt; 0x20)); } int num3 = (numRef[0] &lt;&lt; 0x18) | (numRef[1] &lt;&lt; 0x10) | (numRef[2] &lt;&lt; 0x08) | (numRef[3] &lt;&lt; 0x00); int num4 = (numRef[4] &lt;&lt; 0x18) | (numRef[5] &lt;&lt; 0x10) | (numRef[6] &lt;&lt; 0x08) | (numRef[7] &lt;&lt; 0x00); return (((long) ((ulong) num4)) | (num3 &lt;&lt; 0x20)); } </code></pre> <p>So what we see here is that if <code>startIndex</code> is congruent to zero modulo eight that a direct cast is done from eight bytes starting at address <code>numRef</code>. This case is handled specially because of alignment issues. The line of code</p> <pre><code>return *(((long *) numRef)); </code></pre> <p>translates directly to</p> <pre><code> ldloc.0 ;pushes local 0 on stack, this is numRef conv.i ;pop top of stack, convert to native int, push onto stack ldind.i8 ;pop address off stack, indirect load from address as long ret ;return to caller, return value is top of stack </code></pre> <p>So we see that in this case the key is the <code>ldind.i8</code> instruction. The CLI is agnostic about the endianness of the underlying machine. It lets the JIT compiler handle that issue. On a little-endian machine, <code>ldind.i8</code> will load higher addresses into more significant bits and on a big-endian machine <code>ldind.i8</code> will load higher addresses into less significant bytes. Therefore, in this case, endianness is handled properly.</p> <p>In the other case, you can see that there is an explicit check of the static property <code>BitConverter.IsLittleEndian</code>. In the case of little endian the buffer is interpreted as little endian (so that memory <code>{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }</code> is interpreted as the long <code>0x0706050403020100</code>) and in case of big endian the buffer is interpreted as big endian (so that memory <code>{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }</code> is interpreted as the long <code>0x0001020304050607</code>). So, for <code>BitConverter</code> it all comes down to the endianness of the underyling machine. I note that you're on an Intel chip on Windows 7 x64. Intel chips are little endian. I note that in Reflector, the static constructor for <code>BitConverter</code> is defined as the following:</p> <pre><code>static BitConverter() { IsLittleEndian = true; } </code></pre> <p>This is on my Windows Vista x64 machine. (It could differ on, say, .NET CF on an XBox 360.) There is no reason for Windows 7 x64 to be any different. Consequently, are you sure that <code>BitConverter.IsLittleEndian</code> is <code>false</code>? It should be <code>true</code> and therefore the behavior that you are seeing is correct.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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