十六进制数C#

时间:2013-04-19 10:41:16

标签: c# hex

我正在尝试用C#读取二进制文件,但我遇到了问题。 我宣布了以下内容:

public static readonly UInt32 NUMBER = 0XCAFEBABE;

然后在从文件的最开头读取时我要求读取前4个字节(已尝试过不同的方法,但这是最简单的):

UInt32 num = in_.ReadUInt32(); // in_ is a BinaryReader

虽然我有4个字节是CA,FE,BA和BE(十六进制),同时将它们转换为UInt我得到不同的值。 NUMBER是3405691582,num是3199925962。 我也尝试过这样做:

byte[] f2 = {0xCA, 0xFE, 0xBA, 0xBE};

,执行BitConverter.ToUInt32(new byte[]{0xCA, 0xFE, 0xBA, 0xBE},0)的结果是3199925962。

任何人都可以帮助我吗?

感谢

2 个答案:

答案 0 :(得分:7)

这是因为你机器的endianness很小。请参阅BitConverter.IsLittleEndian属性进行检查。

基本上,数字以反向字节顺序存储,与将它们写下来的方式相比较。我们在左边写了最重要的数字,但是(小端)PC在左边存储最小有效字节。因此,您获得的结果实际上是0xBEBAFECA(十进制3199925962)而不是您的预期。

您可以使用位移操作进行转换:

uint value = (f2[0] << 24) | (f2[1] << 16) | (f2[2] << 8) | f2[3];

还有很多方法可以转换,包括IPAddress.NetworkToHostOrder,正如I4V指出的那样,f2.Reverse()等等。

对于您的具体代码,我认为这是最实用的:

uint num = (uint)IPAddress.NetworkToHostOrder(in_.ReadInt32());

然而,这可能会导致算术下溢,因此可能会导致/checked compiler option or checked keyword出现问题(两者都不常见)。

如果您想处理这些情况并获得更清晰的代码,请将其包装在扩展方法中:

public static uint ReadUInt32NetworkOrder(this BinaryReader reader)
{
    unchecked
    {
        return (uint)IPAddress.NetworkToHostOrder(reader.ReadInt32());    
    }
}

答案 1 :(得分:3)

这就是所谓的byte order

var result1 = BitConverter.ToUInt32(new byte[] { 0xCA, 0xFE, 0xBA, 0xBE }, 0);
//3199925962

var result2 = BitConverter.ToUInt32(new byte[] { 0xBE, 0xBA, 0xFE, 0xCA }, 0);
//3405691582