Conta. Si desidera che il confronto abbia lo stesso risultato del confronto di SQL Server. SQL Server utilizza confronti senza segno sui tipi binari:
select case when 0x0FFFFFFFFFFFFFFF < 0xFFFFFFFFFFFFFFFF then 'unsigned' else 'signed' end
Se fai la stessa cosa con long
che è firmato, 0xFFFFFFFFFFFFFFFF
rappresenta -1
. Ciò significa che il tuo confronto non sarà corretto; non corrisponderà allo stesso confronto eseguito in SQL Server.
Quello che vuoi assolutamente è usare ulong
dove 0xFFFFFFFFFFFFFFFF
è ulong.MaxValue
.
Anche l'endianità è importante
Inoltre, come ha sottolineato Mark, BitConverter.GetUInt64
non si converte correttamente. Mark non ha completamente ragione - BitConverter
è big-endian o little-endian a seconda del sistema su cui è in esecuzione. Puoi vedere di persona
. Inoltre, anche se BitConverter è sempre stato little-endian, Array.Reverse
è meno performante con un'allocazione heap e la copia byte per byte. BitConverter
è semplicemente non semanticamente o praticamente lo strumento giusto per il lavoro.
Questo è quello che vuoi:
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];
}
La soluzione più pulita
Aggiorna :se utilizzi .NET Core 2.1 o versioni successive (o .NET Standard 2.1), puoi utilizzare BinaryPrimitives.ReadUInt64BigEndian
che si adatta perfettamente.
Su .NET Framework, ecco la soluzione che utilizzo:Timestamp.cs
. Fondamentalmente dopo aver trasmesso a Timestamp
, non puoi sbagliare.