Esiste una funzione in C# che prende due interi a 32 bit (int) e restituisce un singolo 64 bit (lungo)?C# - Creazione di un Int64 da due Int32
Sembra che ci dovrebbe essere un modo semplice per farlo, ma non sono riuscito a trovare una soluzione.
Esiste una funzione in C# che prende due interi a 32 bit (int) e restituisce un singolo 64 bit (lungo)?C# - Creazione di un Int64 da due Int32
Sembra che ci dovrebbe essere un modo semplice per farlo, ma non sono riuscito a trovare una soluzione.
provare la seguente
public long MakeLong(int left, int right) {
//implicit conversion of left to a long
long res = left;
//shift the bits creating an empty space on the right
// ex: 0x0000CFFF becomes 0xCFFF0000
res = (res << 32);
//combine the bits on the right with the previous value
// ex: 0xCFFF0000 | 0x0000ABCD becomes 0xCFFFABCD
res = res | (long)(uint)right; //uint first to prevent loss of signed bit
//return the combined result
return res;
}
Prova
(long)(((long)i1 << 32) | (long)i2)
sposta il primo int data da 32 bit (la lunghezza di un int), poi RUP nella seconda int, così si finisce con i due ints concatenati insieme in un lungo.
Questo dovrebbe fare il trucco
((Int64) a << 32 | b)
Dove a
e b
sono Int32. Anche se potresti voler controllare cosa succede con i bit più alti. O semplicemente mettilo dentro un blocco "unchecked
{...}".
Bisogna stare attenti con un po 'di bit di questo tipo, anche se si avranno problemi con le macchine little endian/big endian (exp Le piattaforme mono non sono sempre little endian). Inoltre devi gestire l'estensione del segno. Matematicamente quanto segue è lo stesso, ma si occupa dell'estensione del segno ed è indipendente dalla piattaforma.
return (long)(high * uint.MaxValue) + low;
Quando jitted in fase di esecuzione si tradurrà in prestazioni simili al bit twiddling. Questa è una delle cose belle delle lingue interpretate.
In realtà, è necessario moltiplicare per 'uint.MaxValue + 1', cioè' 0x100000000', non '0x11111111' – Sphinxxx
Solo per chiarezza ... Mentre la risposta accettata sembra funzionare correttamente. Tutti i singoli rivestimenti presentati non sembrano produrre risultati accurati.
Ecco un uno di linea che fa il lavoro:
long correct = (long)left << 32 | (long)(uint)right;
Ecco alcuni codice in modo da poter testare di persona:
long original = 1979205471486323557L;
int left = (int)(original >> 32);
int right = (int)(original & 0xffffffffL);
long correct = (long)left << 32 | (long)(uint)right;
long incorrect1 = (long)(((long)left << 32) | (long)right);
long incorrect2 = ((Int64)left << 32 | right);
long incorrect3 = (long)(left * uint.MaxValue) + right;
long incorrect4 = (long)(left * 0x100000000) + right;
Console.WriteLine(original == correct);
Console.WriteLine(original == incorrect1);
Console.WriteLine(original == incorrect2);
Console.WriteLine(original == incorrect3);
Console.WriteLine(original == incorrect4);
Er, non che dovrebbe essere: long res = left; res = (res << 32) res | = destra; ritorno; ?? – ParoXoN
Penso che tu intenda (ris. << 32) sopra. –
grazie, anche se potresti spiegare come funziona? Mi piacerebbe capire il codice, se possibile. – DarkAmgine