如何BitConverter.ToInt32工作

本文关键字:工作 ToInt32 BitConverter 如何 | 更新日期: 2023-09-27 18:13:07

这是一个方法-

using System;
class Program
{
    static void Main(string[] args)
    {
        //
        // Create an array of four bytes.
        // ... Then convert it into an integer and unsigned integer.
        //
        byte[] array = new byte[4];
        array[0] = 1; // Lowest
        array[1] = 64;
        array[2] = 0;
        array[3] = 0; // Sign bit
        //
        // Use BitConverter to convert the bytes to an int and a uint.
        // ... The int and uint can have different values if the sign bit differs.
        //
        int result1 = BitConverter.ToInt32(array, 0); // Start at first index
        uint result2 = BitConverter.ToUInt32(array, 0); // First index
        Console.WriteLine(result1);
        Console.WriteLine(result2);
        Console.ReadLine();
    }
}

输出

1638516385

我只想知道这是怎么发生的?

如何BitConverter.ToInt32工作

BitConverter.ToInt32的文档实际上有一些很好的例子。假设BitConverter.IsLittleEndian返回true, array[0]是最低有效字节,如您所示…虽然array[3]不只是符号位,但它是最重要的字节,包括符号位(作为第7位),但其余的位用于大小。

所以在你的例子中,最低有效位字节是1,下一个字节是64 -所以结果是:

( 1 * (1 << 0) ) +    // Bottom 8 bits
(64 * (1 << 8) ) +    // Next 8 bits, i.e. multiply by 256
( 0 * (1 << 16)) +    // Next 8 bits, i.e. multiply by 65,536
( 0 * (1 << 24))      // Top 7 bits and sign bit, multiply by 16,777,216

等于16385。如果设置了符号位,则需要以不同的方式考虑这两种情况,但在这种情况下很简单。

转换成以256为基数的数字。所以在你的例子中:1+64*256 = 16385

查看。net 4.0框架参考源代码,BitConverter确实按照Jon的回答工作,尽管它使用指针(unsafe代码)来处理数组。

然而,如果第二个参数(即startindex)可以被4整除(如您的示例中的情况),则框架采取快捷方式。它接受指向value[startindex]byte指针,将其强制转换为int指针,然后对其解引用。无论IsLittleEndian是否为真,此技巧都有效。

从高层次来看,这基本上只是意味着代码指向byte数组中的4个字节,并明确声明,"那里的内存块是int !"(然后返回它的副本)。当您考虑到在底层,int 只是一块内存时,这是完全合理的。

下面是框架ToUint32方法的源代码:
return (uint)ToInt32(value, startIndex);

array[0] = 1;//最低//0x01
array[1] = 64;//0x40
array[2] = 0;//0x00
array[3] = 0;//符号位0 x00

如果合并每个十六进制值0x00004001

MSDN文档解释了

您可以自己查找- https://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs,e8230d40857425ba

如果数据是字对齐的,它只会将内存指针强制转换为int32类型。

return *((int *) pbyte);

否则,它使用字节内存指针值的位逻辑。

对于那些对Little Endien和Big Endien有问题的人。我使用下面的包装器函数来处理它。

    public static Int16 ToInt16(byte[] data, int offset)
    {
        if (BitConverter.IsLittleEndian)
        {
            return BitConverter.ToInt16(BitConverter.IsLittleEndian ? data.Skip(offset).Take(2).Reverse().ToArray() : data, 0);
        }
        return BitConverter.ToInt16(data, offset);
    }
    public static Int32 ToInt32(byte[] data, int offset)
    {
        if (BitConverter.IsLittleEndian)
        {
            return BitConverter.ToInt32(BitConverter.IsLittleEndian ? data.Skip(offset).Take(4).Reverse().ToArray() : data, 0);
        }
        return BitConverter.ToInt32(data, offset);
    }
    public static Int64 ToInt64(byte[] data, int offset)
    {
        if (BitConverter.IsLittleEndian)
        {
            return BitConverter.ToInt64(BitConverter.IsLittleEndian ? data.Skip(offset).Take(8).Reverse().ToArray() : data, 0);
        }
        return BitConverter.ToInt64(data, offset);
    }