这很重要。您希望您的比较结果与 SQL Server 的比较结果相同。SQL Server 对二进制类型使用无符号比较:
select case when 0x0FFFFFFFFFFFFFFF < 0xFFFFFFFFFFFFFFFF then 'unsigned' else 'signed' end
如果你用long
签名做同样的事情,0xFFFFFFFFFFFFFFFF
代表-1
. 这意味着您的比较将不正确;它与在 SQL Server 中进行的相同比较不匹配。
您绝对想要的是使用ulong
where 0xFFFFFFFFFFFFFFFF
is ulong.MaxValue
。
字节序也很重要
此外,正如马克指出的那样,BitConverter.GetUInt64
没有正确转换。马克并不完全正确-BitConverter
是大端还是小端取决于它运行的系统。你可以自己看看这个。此外,即使 BitConverter 始终是 little-endian,Array.Reverse
在堆分配和逐字节复制方面的性能也较差。BitConverter
只是在语义上或实际上不是工作的正确工具。
这就是你想要的:
static ulong BigEndianToUInt64(byte[] bigEndianBinary)
{
return ((ulong)bigEndianBinary[0] << 56) |
((ulong)bigEndianBinary[1] << 48) |
((ulong)bigEndianBinary[2] << 40) |
((ulong)bigEndianBinary[3] << 32) |
((ulong)bigEndianBinary[4] << 24) |
((ulong)bigEndianBinary[5] << 16) |
((ulong)bigEndianBinary[6] << 8) |
bigEndianBinary[7];
}
最干净的解决方案
更新:如果您使用 .NET Core 2.1 或更高版本(或 .NET Standard 2.1),您可以使用BinaryPrimitives.ReadUInt64BigEndian
非常合适的版本。
在 .NET Framework 上,这是我使用的解决方案:Timestamp.cs。基本上,一旦你投到Timestamp
,你就不会出错。