2009-05-05 19 views
9

क्या सी # में कोई फ़ंक्शन है जो दो 32 बिट पूर्णांक (int) लेता है और एक 64 बिट एक (लंबा) देता है?सी # - दो Int32s से एक Int64 बनाना

लगता है जैसे ऐसा करने का एक आसान तरीका होना चाहिए, लेकिन मुझे कोई समाधान नहीं मिला।

उत्तर

18

प्रयास करें निम्नलिखित

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

एर, कि नहीं होना चाहिए: लंबे res = left; res = (res << 32) res | = दाएं; रिटर्न रेस; ?? – ParoXoN

+0

मुझे लगता है कि आपका मतलब है (res << 32) ऊपर। –

+0

धन्यवाद, हालांकि आप यह समझा सकते हैं कि यह कैसे काम करता है? यदि संभव हो तो मैं कोड को समझना चाहता हूं। – DarkAmgine

5

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

प्रयास करें इस बदलाव पहले पूर्णांक 32 बिट (एक पूर्णांक की लंबाई), तो दूसरी पूर्णांक में ओआरएस द्वारा छोड़ा है, तो आप अंत एक साथ लंबे समय में दो स्याही एक साथ मिलकर।

2

यह चाल

((Int64) a << 32 | b) 

कहाँ a और b Int32 हैं क्या करना चाहिए। यद्यपि आप जांचना चाहेंगे कि उच्चतम बिट्स के साथ क्या होता है। या बस इसे "unchecked {...}" ब्लॉक के अंदर रखें।

2

इस तरह थोड़ा झुकाव से सावधान रहना चाहिए, हालांकि आपको थोड़ा एंडियन/बड़ी एंडियन मशीनों पर विस्तार होगा (एक्सपी मोनो प्लेटफॉर्म हमेशा छोटे एंडियन नहीं होते हैं)। इसके अलावा आपको विस्तार के साथ सौदा करना होगा। गणितीय रूप से निम्नलिखित एक ही है लेकिन साइन एक्सटेंशन से संबंधित है और मंच अज्ञेयवादी है।

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

रनटाइम पर लगाए जाने पर इसका परिणाम बिट ट्विडलिंग के समान होगा। यह व्याख्या की गई भाषाओं के बारे में अच्छी चीजों में से एक है।

+0

दरअसल, आपको 'uint.MaxValue + 1', i.e '0x100000000' द्वारा गुणा करने की आवश्यकता है,' 0x11111111' नहीं – Sphinxxx

6

बस स्पष्टता के लिए ... जबकि स्वीकृत उत्तर सही तरीके से काम करने लगता है। प्रस्तुत किए गए सभी लाइनर सटीक परिणाम उत्पन्न नहीं करते हैं।

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

यहाँ कुछ कोड ताकि आप अपने आप के लिए यह परीक्षण कर सकते हैं है:

यहाँ एक एक लाइनर करता है काम है

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); 
संबंधित मुद्दे