2009-05-05 15 views

cevap

18

aşağıdaki

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; 
} 
+0

Er, bu olmamalı: long res = left; res = (res << 32) res | = right; geri dönüş; ?? – ParoXoN

+0

Bence yukarıda (res << 32) demek istiyorsun. –

+0

teşekkürler, bunun nasıl çalıştığını açıklayabilir misiniz? Mümkünse kodu anlamak isterim. – DarkAmgine

5

Bu kayar

(long)(((long)i1 << 32) | (long)i2) 

deneyin deneyin birinci int kadar sonuna kadar, 32 bit (int uzunluğu), ikinci aramadde daha sonra ors bıraktığı İki ints ile birlikte uzun bir araya getirildi.

2

Bu hile a ve b Int32 olan

((Int64) a << 32 | b) 

yapmalıdır. Her ne kadar en yüksek bitlerle ne olduğunu kontrol etmek isteyebilirsiniz. Veya sadece bir "unchecked {...}" bloğunun içine koyun.

2

Böyle küçük bit/büyük endian makinelerinde (exp Mono platformları her zaman küçük endian değildir) sorunlara sahip olmanıza rağmen, bunun gibi biraz çiftleşmeye dikkat etmelisiniz. Artı işaretini uzatmak zorundasın. Matematiksel olarak aşağıdakiler aynıdır ancak işaret uzantısı ile ilgilidir ve platform agnostiktir. zamanında jitted zaman

return (long)(high * uint.MaxValue) + low; 

o biraz twiddling benzer performansa neden olur. Bu, yorumlanmış diller hakkında güzel şeylerden biri.

+0

Aslında, 'uint.MaxValue + 1', yani 0x100000000 'ile değil, 0x11111111 ile çoğaltmanız gerekir. – Sphinxxx

6

Sadece açıklık için ... Kabul edilen yanıt doğru şekilde çalışıyor gibi görünür. Sunulan bütün gömleklerin hepsi doğru sonuçlar üretmiyor gibi görünmektedir.

İşte
long correct = (long)left << 32 | (long)(uint)right; 

bunu kendin için test edebilirsiniz böylece bazı kodudur: Burada

nasıl çalışır bir astar olan

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);