सवाल हस्ताक्षरित पूर्णांक को एक हस्ताक्षरित लंबे समय में परिवर्तित करने का सबसे अच्छा तरीका?


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

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

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


44
2018-03-06 05:57


मूल




जवाब:


कुछ इस तरह?

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

या क्या मैं कुछ न कुछ भूल रहा हूं?

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

81
2018-03-06 06:00



+1 सही है। नहीं, यह मैं था कि कुछ खो रहा था - मैंने खुद को व्यापक रूप से रूपांतरणों के साथ भ्रमित कर दिया और सरल दृष्टिकोण की दृष्टि खो दी =) - maerics
मेह, ऐसा होता है। विशेष रूप से सी ++ में जहां सब कुछ करने के लिए एक बेजीलियन तरीके हैं। - Mysticial
चाहेंगे x & 0xFFFFFFFFL काम भी? - Sebastian Hoffmann
@Paranaix मुझे विश्वास है कि यह भी काम करेगा। यह थोड़ी देर हो गया है क्योंकि मैंने यह जवाब लिखा था, इसलिए मुझे लगता है कि मैंने शून्य के साथ गद्दी क्यों की थी, क्योंकि मैं ज्यादातर सी ++ करता हूं और पूर्णांक पदोन्नति नियम हस्ताक्षरित / हस्ताक्षरित प्रकारों के साथ अधिक जटिल होते हैं। - Mysticial
धन्यवाद, मुर्मूर हैश का उपयोग करके इस मुद्दे में भाग गया। - Richard Clayton


जावा 8 में मानक तरीका है Integer.toUnsignedLong(someInt), जो बराबर है @ मिस्टिकियल का जवाब


25
2018-06-30 12:37





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


16
2018-03-06 06:37





आप एक समारोह का उपयोग कर सकते हैं

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

हालांकि ज्यादातर मामलों में आपको ऐसा करने की आवश्यकता नहीं है। आप इसके बजाय वर्कअराउंड का उपयोग कर सकते हैं। जैसे

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

हस्ताक्षर किए गए मानों का उपयोग करने के लिए वर्कअराउंड के अधिक उदाहरणों के लिए। बिना हस्ताक्षर किए उपयोगिता वर्ग


7
2018-03-06 08:27



आपका getUnsignedInt फ़ंक्शन काम नहीं करता है। मैंने अपने कार्यक्रम में एक गंभीर त्रुटि की क्योंकि मैंने इसका परीक्षण नहीं किया था। : (( - user2707175
@ user2707175 परिवर्तन >>> सेवा मेरे >> और यह काम करना चाहिए - Jeff Jones
getUnsignedInt के रूप में काम करने के लिए प्रतीत होता है। >>> सही है। >> साइन एक्सटेंशन का कारण बनता है, और -1L सही एक्सटेंशन के साथ स्थानांतरित होता है, किसी भी राशि का परिणाम हमेशा सभी के साथ एक मूल्य में होता है। - Macil


अन्य समाधान

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

2
2018-03-06 06:19



Math.pow बहुत महंगा है और हर बार गणना की जाती है। तुलना से 1l << 32 तेज़ है और केवल संकलक द्वारा गणना की जाती है। (और एक लंबे समय तक कास्ट करने की जरूरत नहीं है। - Peter Lawrey
क्या आप कृपया मुझे कुछ रूपांतरण या विवरण दे सकते हैं कि ये रूपांतरण कैसे काम करते हैं, मैं इसे समझने में सक्षम नहीं हूं। - ManMohan Vyas
क्योंकि int 32 बिट है और प्रतिनिधित्व के लिए दो पूरक का उपयोग करें। आप विकिपीडिया में दो पूरक की जांच कर सकते हैं (en.wikipedia.org/wiki/Two's_complement) अधिक जानकारी प्राप्त करने के लिए - lmatt


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

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

के बजाय:

वापसी x और 0xFFFFFFFFL;

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


-2
2018-03-05 11:27



यह पूरी तरह गलत है। Int को लंबे समय तक प्रचारित किया जाता है, और फिर आप इसे 64 लोगों की एक बिट स्ट्रिंग के साथ मास्क कर रहे हैं जो कुछ भी नहीं करता है। 42 9 4 9 672 9 5 के बजाय निम्नलिखित प्रिंट -1: int i = -1; लंबा जे = मैं और (~ 0 एल); Println (जे); - PBJ
हाँ यह मेरा बुरा है, मैंने ~ 0 एल के साथ 0xFFFFFFFFL को भ्रमित कर दिया जो स्पष्ट है कि यह मामला नहीं है - okoopat


long abs(int num){
    return num < 0 ? num * -1 : num;
}

-4
2017-11-19 09:31



कृपया दो के पूरक पढ़ें (en.wikipedia.org/wiki/Two%27s_complement) जो वर्णन करता है कि हस्ताक्षरित संख्याओं का आमतौर पर प्रतिनिधित्व कैसे किया जाता है। आप उस मुद्दे को हल करने के लिए केवल पूर्ण मूल्य नहीं ले सकते हैं (tadej.me/twos-complement-and-absolute-values)। - Stepan Pogosyan