Het maakt wel uit. U wilt dat uw vergelijking hetzelfde resultaat heeft als de vergelijking van SQL Server. SQL Server gebruikt niet-ondertekende vergelijkingen op binaire typen:
select case when 0x0FFFFFFFFFFFFFFF < 0xFFFFFFFFFFFFFFFF then 'unsigned' else 'signed' end
Als je hetzelfde doet met long
die is ondertekend, 0xFFFFFFFFFFFFFFFF
staat voor -1
. Dat betekent dat uw vergelijking niet klopt; het komt niet overeen met dezelfde vergelijking in SQL Server.
Wat je zeker wilt, is om ulong
. te gebruiken waar 0xFFFFFFFFFFFFFFFF
is ulong.MaxValue
.
Endianness is ook belangrijk
Bovendien, zoals Mark opmerkte, BitConverter.GetUInt64
converteert niet goed. Mark heeft niet helemaal gelijk - BitConverter
is big-endian of little-endian, afhankelijk van het systeem waarop het draait. U kunt dit zelf zien
. En zelfs als BitConverter altijd little-endian was, Array.Reverse
is minder performant met een heaptoewijzing en byte-by-byte kopiëren. BitConverter
is gewoon semantisch of praktisch niet de juiste tool voor de klus.
Dit is wat je wilt:
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];
}
De schoonste oplossing
Bijwerken :Als u .NET Core 2.1 of hoger (of .NET Standard 2.1) gebruikt, kunt u BinaryPrimitives.ReadUInt64BigEndian
die perfect past.
Op .NET Framework is hier de oplossing die ik gebruik:Timestamp.cs
. In principe zodra je cast naar Timestamp
, je kunt niet fout gaan.