2015-09-08 12 views
7

मैंने आईटी का अध्ययन नहीं किया, और केवल हाल ही में bit shifts और two's complement के लिए एक आवेदन आया। तो, क्या आप कृपया अपने स्पष्टीकरण में सरल अंग्रेजी का उपयोग कर सकते हैं और मान सकते हैं कि मुझे आईपी पते, बिट ऑपरेशंस और जावा डेटाटाइप के बारे में कुछ भी पता नहीं है?जावा का बिट शिफ्ट ऑपरेटर हुड के नीचे कैसे काम करता है?

long m = (-1) << (byte) 16; 

अब, यह आईपी सबनेट मास्किंग के लिए है:

आज, मैं कोड का निम्न भाग (संक्षिप्त) पाया। मुझे पता है कि मुझे 8 बिट्स (यानी 4 बाइट्स) के 4 ब्लॉक के साथ शुरू करने की आवश्यकता है, और सभी बिट्स को "चालू" होना चाहिए: 11111111 11111111 1111111 1111111 अगला, शून्य से दाईं ओर शून्य स्थानांतरित हो जाते हैं, इस मामले में 16 बिट्स के लायक होते हैं; इसलिए हमें 11111111 11111111 00000000 0000000, मास्क मिलता है।

  1. 16 इस काम करने के लिए प्रकार byte का होना जरूरी है:

    लेकिन मैं ऐसा कुछ प्रश्न हैं?

  2. परिणाम long का प्रकार है। जब उपरोक्त अभिव्यक्ति चलता है, -1 रूपांतरित हो जाता है - प्रभावी ढंग से - 4x8bit ब्लॉक। जावा कैसे जानता है कि इसे 32 पदों/बिट्स (एक आईपी पता 'लंबाई) की जरूरत है, और नहीं, कहें, 16, या 8, दो पूरक के आवेदन करते समय? (मुझे लगता है कि long डेटाटाइप के साथ क्या करना है?)
  3. दो के पूरक -1 पर क्यों शुरू होते हैं? (Google आपको -0b1 देता है यदि आप इसे पूछते हैं कि -1 बाइनरी में है। मैंने पहले सोचा था कि यह ओवरफ़्लो के साथ हो सकता है, लेकिन ऐसा नहीं है, है ...?)
  4. वास्तव में, कंपाइलर कनवर्ट करने वाला डेटाटाइप यह कोड चलाने के दौरान, यह सब काम करने के लिए?

अद्यतन:16 एक विधि द्वारा रनटाइम पर उत्पादन किया जाता है; मैंने यहां एक उदाहरण के रूप में एक स्थिर रखा है। मसा में शायद एक बुरा विचार ...

+0

एक 32 बिट मान एक रजिस्टर में फिट होगा, और बिट्सफ़िफ्टिंग ऑपरेशन आमतौर पर प्रोसेसर द्वारा किया जाएगा, कुछ ऐसा जो असेंबली में 'shl AX, 16' जैसा दिखता है। उस स्तर पर वास्तव में डेटा प्रकार नहीं हैं। आपको अभी 8, 16, 32 या 64 बिट्स के ब्लॉक मिल गए हैं। – GolezTrol

+1

32 बिट्स के साथ लगभग निश्चित रूप से अधिक करना है कि वास्तविक int 32 बिट्स चौड़ा है, जो कि आईपी की लंबाई है (जहां तक ​​मुझे याद है, जावा में बिट्सफिफ्ट करते समय, सबकुछ स्वचालित रूप से int में प्रचारित होता है) – Luke

+1

आपके चार में से कोई भी नहीं प्रश्नों के साथ कुछ भी करना है कि कैसे बदलाव हुड के नीचे काम करता है, इसलिए आपको शायद अधिक वर्णनात्मक शीर्षक का उपयोग करना चाहिए। – harold

उत्तर

2

यह वास्तव में भ्रामक है कि आपके m चर long प्रकार का है एक आईपी पता 32-बिट है और एक int से मेल खाती है क्योंकि। आपका दायां हाथ वास्तव में int है और इसकी पूरी गणना के बाद ही यह long (64-बिट) तक बढ़ा है। आपके सवालों का जवाब:

  1. ऐसा नहीं है। आप कास्ट हटा सकते हैं।
  2. परिणाम वास्तव में int प्रकार का है, लेकिन long में परिवर्तित हो जाता है क्योंकि m के प्रकार की आवश्यकता है।
  3. दो का पूरक वास्तव में कुछ भी "लागू" नहीं है। संख्या -1दो पूरक में एन्कोड किया गया है। आपको कुछ की आवश्यकता है, जो कि बिट्स के अलावा कुछ भी नहीं है। इसके अलावा, यहां दो पूरक पूरक भूमिका निभाते हैं: यह लगभग -1 को सभी 1-बिट्स के रूप में एन्कोड किया जा रहा है।
  4. यह सिर्फ 32 एक-बिट्स को बाईं ओर स्थानांतरित किया जा रहा है, रिक्तियों में भरने वाले शून्य। फिर, long में कनवर्ट करने के लिए, बाईं ओर 32 और 1-बिट जोड़े गए हैं।
+0

ठीक है, तो, अगले दाफ्ट प्रश्न: क्या जावा में सभी संख्या दो पूरक के साथ एन्कोडेड हैं? यदि हां, तो क्या इसका मतलब यह है कि जावा में एक पूर्णांक 32 बिट लंबा/बड़ा होता है, लेकिन वास्तव में केवल संख्यात्मक डेटा के 31 बिट होते हैं, और प्रमुख बिट का उपयोग यह इंगित करने के लिए किया जाता है कि यह सकारात्मक या नकारात्मक संख्या है या नहीं? (यानी, क्या एमएसबी हमेशा साइन बिट है?) – Christian

+1

सभी _signed integers_ दो पूरक में हैं और यह जावा-विशिष्ट नहीं है। वास्तव में उपयोग में कोई अन्य represetation नहीं है। मैं साइन से "संख्यात्मक डेटा" अलग नहीं करता क्योंकि सभी 32 बिट समान रूप से 2^32 विशिष्ट पूर्णांक का प्रतिनिधित्व करने में सहयोग करते हैं। –

6

वास्तव में, क्या डेटाटाइप्स संकलक इस जबकि यह कोड चल रहा है करने के लिए कनवर्ट करता है, यह सब काम करने के लिए?

यह

(-1) << (byte) 16; 

एक constant expression है। इसका मूल्य संकलन समय पर जाना जाता है। यह long है -65536 (दशमलव प्रतिनिधित्व में) के साथ।

यदि अभिव्यक्ति निरंतर अभिव्यक्ति नहीं थी, तो अभिव्यक्ति का मूल्यांकन करते समय चर का प्रकार कोई फर्क नहीं पड़ता। यह केवल बाद में मायने रखता है जब उसका मान चर के लिए असाइन किया जाता है। उदाहरण के लिए

लें

int i = -1; 
long m = i << (byte) 16; 

अभिव्यक्ति ऊपर एक है कि एक पारी ऑपरेटर और दो ऑपरेंड, शामिल है प्रकार int में से एक और प्रकार byte का एक और।

The JLS states the following concerning shift operators and their operands

एकल संख्यात्मक पदोन्नति (§5.6.1) अलग से प्रत्येक संकार्य पर किया जाता है।

which is

अन्यथा, यदि संकार्य संकलन समय प्रकार बाइट, लघु, या चार की है, यह प्रकार int के एक मूल्य के लिए एक को चौड़ा आदिम रूपांतरण द्वारा प्रोत्साहित किया जाता है (§5.1.2) ।

तो byte मान int तक बढ़ाया गया है। तो आपके पहले सवाल के लिए नहीं।

अभिव्यक्ति का परिणाम int (32 बिट्स) का मान होगा। इसे long (64 बिट्स) चर के लिए असाइन किया जाना है, इसलिए आवंटित होने से पहले मूल्य widened to a long होगा।

JLS again

अभिन्न प्रकार बाइट, लघु, पूर्णांक, और लंबे होते हैं, जिनके मान 8 बिट, 16 बिट, 32-बिट और 64-बिट पर हस्ताक्षर किए two's-पूरक हैं से

पूर्णांक, क्रमशः, और चार, जिनके मान 16-बिट हस्ताक्षरित पूर्णांक यूटीएफ -16 कोड इकाइयों (§3.1) का प्रतिनिधित्व करते हैं।

इस तरह वे संग्रहीत किए जाते हैं।

+0

नाइटपिक: आप खुद के विरोधाभास प्रतीत होते हैं। "अभिव्यक्ति का परिणाम प्रकार int का मान है" और "यह मान के साथ लंबा है"। – Taemyr

+0

@Tememyr बेहतर? –

+0

तो, कम अकादमिक शर्तों में, दोनों पक्षों की संख्या 'int' है, लेकिन - क्योंकि यह बिट स्तर पर एक ऑपरेशन है - हम उनके बिट मान/प्रस्तुतियों को देखते हैं? और क्योंकि जावा में एक पूर्णांक 32 बिट्स है, और दोनों के पूरक के लिए धन्यवाद, '-1' 32 '1' बिट्स (जब हम इसका थोड़ा सा प्रतिनिधित्व देखते हैं) होते हैं? – Christian

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