2012-03-06 17 views
42

जावा में कुछ हैश फ़ंक्शंस के लिए मान को एक हस्ताक्षरित पूर्णांक के रूप में देखना अच्छा लगेगा (उदा। अन्य कार्यान्वयन की तुलना के लिए) लेकिन जावा केवल हस्ताक्षरित प्रकारों का समर्थन करता है। हम इस तरह के रूप में एक "अहस्ताक्षरित" long को एक हस्ताक्षरित int परिवर्तित कर सकते हैं:हस्ताक्षरित पूर्णांक को एक हस्ताक्षरित लंबे समय में परिवर्तित करने का सबसे अच्छा तरीका?

public static final int BITS_PER_BYTE = 8; 
public static long getUnsignedInt(int x) { 
    ByteBuffer buf = ByteBuffer.allocate(Long.SIZE/BITS_PER_BYTE); 
    buf.putInt(Integer.SIZE/BITS_PER_BYTE, x); 
    return buf.getLong(0); 
} 
getUnsignedInt(-1); // => 4294967295 

हालांकि, इस समाधान क्या हम वास्तव में कर रहे हैं के लिए overkill की तरह लगता है। क्या एक ही चीज़ हासिल करने का एक और अधिक प्रभावी तरीका है?

उत्तर

78

ऐसा कुछ?

int x = -1; 
long y = x & 0x00000000ffffffffL; 

या क्या मुझे कुछ याद आ रही है?

public static long getUnsignedInt(int x) { 
    return x & 0x00000000ffffffffL; 
} 
+0

+1 दाएं। नहीं, यह मैं था जो कुछ खो रहा था - मैंने खुद को व्यापक रूप से रूपांतरणों के साथ भ्रमित कर दिया और सरल दृष्टिकोण की दृष्टि खो दी =) – maerics

+0

मेह, ऐसा होता है। विशेष रूप से सी ++ में जहां सब कुछ करने के लिए एक बेजीलियन तरीके हैं। – Mysticial

+4

क्या 'x और 0xFFFFFFFFL' भी काम करेगा? – Paranaix

2

अन्य समाधान।

public static long getUnsignedInt(int x) { 
    if(x > 0) return x; 
    long res = (long)(Math.pow(2, 32)) + x; 
    return res; 
} 
+4

Math.pow बहुत महंगा है और हर बार गणना की जाती है। तुलनात्मक रूप से '1 एल << 32' तेज है और केवल संकलक द्वारा गणना की जाती है। (और एक लंबे को डाली जा करने के लिए पूर्णांक है क्योंकि 32 बिट की जरूरत नहीं है। –

+0

तुम मुझे कैसे इन रूपांतरण काम करते हैं, यह समझ नहीं पा रहा हूँ पर कुछ लिंक या विवरण दे कृपया कर सकते हैं। –

+1

और दो के पूरक का उपयोग आप। प्रतिनिधित्व करने के लिए विकिपीडिया (http://en.wikipedia.org/wiki/Two's_complement) अधिक जानकारी के – lmatt

15

GuavaUnsignedInts.toLong(int) ... के साथ-साथ अहस्ताक्षरित पूर्णांकों पर अन्य उपयोगिताओं की एक किस्म प्रदान करता है।

7

आप हालांकि ज्यादातर मामलों यदि आप ऐसा करने की जरूरत नहीं है में

public static long getUnsignedInt(int x) { 
    return x & (-1L >>> 32); 
} 

की तरह एक समारोह का उपयोग कर सकते हैं। आप इसके बजाय वर्कअराउंड का उपयोग कर सकते हैं। जैसे

public static boolean unsignedEquals(int a, int b) { 
    return a == b; 
} 

हस्ताक्षरित मानों का उपयोग करने के लिए कामकाज के अधिक उदाहरणों के लिए। Unsigned utility class

+0

आपका getUnsignedInt समारोह काम नहीं करता है प्राप्त करने के लिए दो के पूरक देख सकते हैं। मैं के रूप में मैं परीक्षण नहीं किया था मेरे कार्यक्रम में एक गंभीर त्रुटि हुई यह:।।। (( – user2707175

+0

@ user2707175 परिवर्तन '' >>> करने के लिए '' >> और यह –

+0

getUnsignedInt काम करने के लिए के रूप में है '' >>> सही है प्रकट होता है काम करना चाहिए '' >> संकेत विस्तार का कारण बनता है, और - 1L संकेत विस्तार किसी भी राशि हमेशा सभी लोगों के साथ एक मूल्य में जो परिणाम के साथ सही-स्थानांतरित कर दिया। – AgentME

-2

बस मेरे 2 सेंट यहाँ है, लेकिन मुझे लगता है कि यह एक अच्छी आदत है उपयोग करने के लिए:

public static long getUnsignedInt(int x) { return x & (~0L); // ~ has precedence over & so no real need for brackets }

के बजाय:

वापसी एक्स & 0xFFFFFFFFL;

इस स्थिति में आपकी चिंता नहीं है कि 'एफ का मुखौटा कितना है। यह हमेशा काम करेगा!

+1

यह पूरी तरह से गलत है। पूर्णांक एक लंबे करने के लिए प्रोत्साहित किया जाता है, और फिर आप 64 लोगों को जो कुछ नहीं करता है का एक सा तार के साथ यह मास्किंग कर रहे हैं। निम्नलिखित प्रिंट -1 इसके बजाय ओ च 4294967295: पूर्णांक मैं = -1; लंबे जे = मैं और (~ 0 एल); System.out.println (जे); – PBJ

+0

हाँ यह मेरा बुरा है, मैंने ~ 0L के साथ 0xFFFFFFFFL को भ्रमित कर दिया जो स्पष्ट है कि यह मामला नहीं है – okoopat

संबंधित मुद्दे